明凯博客

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

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

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

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

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

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

简单工厂模式

工厂方法模式

抽象工厂模式

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

工厂模式的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
< ?php
//抽象产品
interface Person {
    public function getName(); 
}
//具体产品实现
class Teacher implements Person {
    public function getName() {
        return "谷歌老师<br>";
    }
}
class Student implements Person {
    public function getName() {
        return "明凯学生<br />";
    }
}
 
//简单工厂
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级谷歌老师

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

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

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

, ,

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注