明凯博客

关注网站技术,一个特立独行的程序员

PHP面对对象设计模式之工厂模式

当我要实例化类的时候,不直接new这个类,而是通过调用另一个类的一个方法来实例化。这就是工厂模式的核心原理。

工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。

使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。

根据抽象程度的不同,PHP工厂模式分为三种:

简单工厂模式

工厂方法模式

抽象工厂模式

工厂模式的原理:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
工厂方法和简单工厂相对,工厂方法增加了许多代码但是实现的功能和简单工厂一样。但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则。
抽象工厂由多条产品线,而工厂方法只有一条产品线,是抽象工厂的简化。
抽象工厂模式只负责抽象工厂接口,具体工厂交给客户去扩展。在分工时,核心工程师负责抽象工厂和抽象产品的定义,业务工程师负责具体工厂和具体产品的实现。

工厂模式的例子

< ?php
//抽象产品
interface Person {
    public function getName(); 
}
//具体产品实现
class Teacher implements Person {
    public function getName() {
        return "谷歌老师
"; } } class Student implements Person { public function getName() { return "明凯学生
"; } } //简单工厂 class SimpleFactory { public static function getPerson($type) { $person = null; if ($type == 'teacher') { $person = new Teacher(); } elseif ($type == 'student') { $person = new Student(); } return $person; } } //简单工厂调用 class SimpleClient { public static function main() { // 如果不用工厂模式,则需要提前指定具体类 // $person = new Teacher(); // echo $person->getName(); // $person = new Student(); // echo $person->getName(); // 用工厂模式,则不需要知道对象由什么类产生,交给工厂去决定 $person = SimpleFactory::getPerson('teacher'); echo $person->getName(); $person = SimpleFactory::getPerson('student'); echo $person->getName(); } } //工厂方法 interface CommFactory { public function getPerson(); } //具体工厂实现 class StudentFactory implements CommFactory { public function getPerson(){ return new Student(); } } class TeacherFactory implements CommFactory { public function getPerson() { return new Teacher(); } } //工厂方法调用 class CommClient { public static function main() { $factory = new TeacherFactory(); echo $factory->getPerson()->getName(); $factory = new StudentFactory(); echo $factory->getPerson()->getName(); } } //抽象工厂模式另一条产品线 interface Grade { function getYear(); } //另一条产品线的具体产品 class Grade1 implements Grade { public function getYear() { return '2016级'; } } class Grade2 implements Grade { public function getYear() { return '2017级'; } } //抽象工厂 interface AbstractFactory { function getPerson(); function getGrade(); } //具体工厂可以产生每个产品线的产品 class Grade1TeacherFactory implements AbstractFactory { public function getPerson() { return new Teacher(); } public function getGrade() { return new Grade1(); } } class Grade1StudentFactory implements AbstractFactory { public function getPerson() { return new Student(); } public function getGrade() { return new Grade1(); } } class Grade2TeacherFactory implements AbstractFactory { public function getPerson() { return new Teacher(); } public function getGrade() { return new Grade2(); } } //抽象工厂调用 class FactoryClient { public function printInfo($factory) { echo $factory->getGrade()->getYear().$factory->getPerson()->getName(); } public static function main() { $client = new FactoryClient(); $factory = new Grade1TeacherFactory(); $client->printInfo($factory); $factory = new Grade1StudentFactory(); $client->printInfo($factory); $factory = new Grade2TeacherFactory(); $client->printInfo($factory); } } //简单工厂 SimpleClient::main(); //工厂方法 CommClient::main(); //抽象工厂 FactoryClient::main(); //

输出:

谷歌老师
明凯学生
谷歌老师
明凯学生
2016级谷歌老师
2016级明凯学生
2017级谷歌老师

工厂模式的用处:
简单工厂模式: 用来生产同一等级结构中的任意产品。(不能增加新的产品)
工厂类负责创建的对象较少,操作时只需知道传入工厂类的参数即可,对于如何创建对象过程不用关心。

工厂方法模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
当一个类不知道它所必须创建对象的类时,希望由子类来指定它所创建的对象。

抽象工厂模式 :用来生产不同产品种类的全部产品。(不能增加新的产品,支持增加产品种类)
系统不依赖于产品类实例如何被创建,组合和表达的细节,系统的产品有多于一个的产品族,而系统只消费其中某一族的产品,同属于同一个产品族是在一起使用的,所有产品以同样的接口出现,从而使客户端不依赖于实现。

, ,

相关文章

1 条评论 “PHP面对对象设计模式之工厂模式

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注