PHP 工厂模式

(一个创造者、一个产品,将类的实例化和对象的使用分离开,这就是工厂模式的思想)
 
工厂模式的确是让初学者比较费解的模式。
首先它有简单工厂和抽象工厂之分。但真正算得上设计模式的,是抽象工厂。而简单工厂说实在的仅仅是比较天然的再封装。因此不少教科书会显摆本身的内涵大幅度的介绍抽象工厂,而有意无心的忽略了简单工厂。
实际的状况又正好相反,简单工厂几乎每一个人都会用得上,抽象工厂大部分人一生都用不上一次。
下面回答你的问题:简单工厂封装了new到底有啥好处?
在实际的项目中,在你通往架构师的道路上,你要培养出一种感受:要new一个实体对象是件很谨慎的事情(不是指值对象),不要随便new。最好不要本身new,让别人去new,传给你去调用。这样new错了也是别人的事,换而言之你的模块是好质量的,禁得起推敲的。那么都不肯意去new,谁去new?让专门的一个工厂去new。请注意:这仅仅是解决new的方式之一,此外还要反射啊等等。那你必需要等到真正接触大型项目才能有体味的。


做者:余叶
连接: https://www.zhihu.com/question/24843188/answer/49197026
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
 
 

1.隐藏具体类名,不少类隐藏得很深的,并且可能会在后续版本换掉
2.避免你辛苦的准备构造方法的参数
3.这个工厂类能够被配置成其它类
4.这个工厂对象能够被传递php

最后来句重要的
new XXX其实也是一种硬编码!!!
 
举一个例子,在游戏中,咱们要一个战士配装备,首先咱们须要配一把枪械(枪械有不少,步枪,狙击枪等,使用问题 1 进行抽象),可是配了枪械以后,咱们还须要配子弹啊(继续使用问题 1 的方法进行抽象),好了,如今能够抽象出 2 层的工厂类了,针对如今的状况咱们是否是可让一个工厂既生产枪械,又生产子弹呢? 这就是 抽象工厂模式。简单来讲, 能够把有一些有联系或者相近的产品,放到一个工厂去生产,没有必要单独再开一个工厂了


概念

工厂模式是咱们最经常使用的实例化对象模式,是用工厂方法代替new操做的一种模式。html

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

根据抽象程度的不一样,PHP工厂模式分为三种:设计模式

  1. 简单工厂模式架构

  2. 工厂方法模式测试

  3. 抽象工厂模式编码

讲解

简单工厂模式

简单工厂模式又称静态工厂方法模式,之因此能够这么说,是由于简单工厂模式是经过一个静态方法来建立对象的。spa

代码示例:设计

<?php header('Content-Type:text/html;charset=utf-8'); /** *简单工厂模式(静态工厂方法模式) */ /** * Interface people 人类 */ interface people { public function say(); } /** * Class man 继承people的男人类 */ class man implements people { // 具体实现people的say方法 public function say() { echo '我是男人<br>'; } } /** * Class women 继承people的女人类 */ class women implements people { // 具体实现people的say方法 public function say() { echo '我是女人<br>'; } } /** * Class SimpleFactoty 工厂类 */ class SimpleFactoty { // 简单工厂里的静态方法-用于建立男人对象 static function createMan() { return new man(); } // 简单工厂里的静态方法-用于建立女人对象 static function createWomen() { return new women(); } } /** * 具体调用 */ $man = SimpleFactoty::createMan(); $man->say(); $woman = SimpleFactoty::createWomen(); $woman->say(); 

运行结果:代理

我是男人
我是女人

工厂方法模式

定义一个用于建立对象的接口,让子类决定哪一个类实例化。 他能够解决简单工厂模式中的封闭开放原则问题。

看代码:

<?php header('Content-type:text/html;charset=utf-8'); /* *工厂方法模式 */ /** * Interface people 人类 */ interface people { public function say(); } /** * Class man 继承people的男人类 */ class man implements people { // 实现people的say方法 function say() { echo '我是男人-hi<br>'; } } /** * Class women 继承people的女人类 */ class women implements people { // 实现people的say方法 function say() { echo '我是女人-hi<br>'; } } /** * Interface createPeople 建立人物类 * 注意:与上面简单工厂模式对比。这里本质区别在于,此处是将对象的建立抽象成一个接口。 */ interface createPeople { public function create(); } /** * Class FactoryMan 继承createPeople的工厂类-用于实例化男人类 */ class FactoryMan implements createPeople { // 建立男人对象(实例化男人类) public function create() { return new man(); } } /** * Class FactoryMan 继承createPeople的工厂类-用于实例化女人类 */ class FactoryWomen implements createPeople { // 建立女人对象(实例化女人类) function create() { return new women(); } } /** * Class Client 操做具体类 */ class Client { // 具体生产对象并执行对象方法测试 public function test() { $factory = new FactoryMan(); $man = $factory->create(); $man->say(); $factory = new FactoryWomen(); $man = $factory->create(); $man->say(); } } // 执行 $demo = new Client; $demo->test();

看结果:

我是男人-hi 我是女人-hi

抽象工厂模式

提供一个建立一系列相关或相互依赖对象的接口。

注意:这里和工厂方法的区别是:一系列(多个),而工厂方法只有一个。

代码:

<?php header('Content-type:text/html;charset=utf-8'); /* * 抽象工厂模式 */ /** * Interface people 人类 */ interface people { public function say(); } /** * Class OneMan 第一个男人类-继承people */ class OneMan implements people { // 实现people的say方法 public function say() { echo '男1:我喜欢你<br>'; } } /** * Class TwoMan 第二个男人类-继承people */ class TwoMan implements people{ // 实现people的say方法 public function say() { echo '男2:我看上你了<br>'; } } /** * Class OneWomen 第一个女人类-继承people */ class OneWomen implements people { // 实现people的say方法 public function say() { echo '女1:我不喜欢你<br>'; } } /** * Class TwoWomen 第二个女人类-继承people */ class TwoWomen implements people { // 实现people的say方法 public function say() { echo '女2:滚一边玩去<br>'; } } /** * Interface createPeople 建立对象类 * 注意:这里将对象的建立抽象成了一个接口。 */ interface createPeople { // 建立第一个 public function createOne(); // 建立第二个 public function createTwo(); } /** * Class FactoryMan 用于建立男人对象的工厂类-继承createPeople */ class FactoryMan implements createPeople { // 建立第一个男人 public function createOne() { return new OneMan(); } // 建立第二个男人 public function createTwo() { return new TwoMan(); } } /** * Class FactoryWomen 用于建立女人对象的工厂类-继承createPeople */ class FactoryWomen implements createPeople { // 建立第一个女人 public function createOne() { return new OneWomen(); } // 建立第二个女人 public function createTwo() { return new TwoWomen(); } } /** * Class Client 执行测试类 */ class Client { // 具体生成对象和执行方法 public function test() { // 男人 $factory = new FactoryMan(); $man = $factory->createOne(); $man->say(); $man = $factory->createTwo(); $man->say(); // 女人 $factory = new FactoryWomen(); $man = $factory->createOne(); $man->say(); $man = $factory->createTwo(); $man->say(); } } // 执行 $demo = new Client; $demo->test();

结果:

1:我喜欢你 男2:我看上你了 女1:我不喜欢你 女2:滚一边玩去

总结

区别

  1. 简单工厂模式(静态方法工厂模式) : 用来生产同一等级结构中的任意产品。(不能增长新的产品)

  2. 工厂模式 :用来生产同一等级结构中的固定产品。(支持增长任意产品)

  3. 抽象工厂 :用来生产不一样产品种类的所有产品。(不能增长新的产品,支持增长产品种类)

适用范围

简单工厂模式:

工厂类负责建立的对象较少,操做时只需知道传入工厂类的参数便可,对于如何建立对象过程不用关心。

工厂方法模式:

知足如下条件时,能够考虑使用工厂模式方法

  1. 当一个类不知道它所必须建立对象的类时

  2. 一个类但愿由子类来指定它所建立的对象时

  3. 当类将建立对象的职责委托给多个帮助子类中得某一个,而且你但愿将哪个帮助子类是代理者这一信息局部化的时

抽象工厂模式:

知足如下条件时,能够考虑使用抽象工厂模式

  1. 系统不依赖于产品类实例如何被建立,组合和表达的细节。

  2. 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品

  3. 同属于同一个产品族是在一块儿使用的。这一约束必须在系统的设计中体现出来。

  4. 系统提供一个产品类的库,全部产品以一样的接口出现,从而使客户端不依赖于实现。

以上几种,归根结底,都是将重复的东西提取出来,以方便总体解耦和复用,修改时方便。可根据具体需求而选择使用。

相关文章
相关标签/搜索