PHP设计模式(一)工厂模式Factory实例详解【创建型】 |
本文实例讲述了PHP设计模式(一)工厂模式Factory 。分享给大家供大家参考,具体如下: 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的 。但是在一些情况下, new操作符直接生成对象会带来一些问题 。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象 。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动 。 模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢? 解决方案:建立一个工厂来创建对象 。 实现: 一、引言 1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用 。 二、分类 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的 。 三、区别工厂方法模式: 抽象工厂模式: 区别: 四、简单工厂模式建立一个工厂(一个函数或一个类方法)来制造新的对象 。 分布说明引子:从无到有 。客户自己创建宝马车,然后拿来用 。 <?php /** * 车子系列 * */ Class BWM320{ function __construct($pa) { } } Class BMW523{ function __construc($pb){ } } /** * * 客户自己创建宝马车 */ class Customer { function createBMW320(){ return new BWM320(); } function createBMW523(){ return new BMW523(); } } 客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节.这就是工业革命了:简单工厂模式 即我们建立一个工厂类方法来制造新的对象 。如图: 产品类: <?php /** * 车子系列 * */ abstract Class BWM{ function __construct($pa) { } } Class BWM320 extends BWM{ function __construct($pa) { } } Class BMW523 extends BWM{ function __construc($pb){ } } 工厂类: /** * * 工厂创建车 */ class Factory { static function createBMW($type){ switch ($type) { case 320: return new BWM320(); case 523: return new BMW523(); //.... } } 客户类: /** * * 客户通过工厂获取车 */ class Customer { private $BMW; function getBMW($type){ $this¬-> BMW = Factory::createBMW($type); } } 简单工厂模式又称静态工厂方法模式 。重命名上就可以看出这个模式一定很简单 。它存在的目的很简单:定义一个用于创建对象的接口 。 先来看看它的组成: 下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式 。当客户不再满足现有的车型号的时候,想要一种速度快的新型车,只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了 。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBMW($type)方法需要新增case),这显然是违背开闭原则的 。可想而知对于新产品的加入,工厂类是很被动的 。对于这样的工厂类,我们称它为全能类 或者上帝类 。 五、工厂方法模式 工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承 。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担 。 1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关 。是具体工厂角色必须实现的接口或者必须继承的父类 。在java中它由抽象类或者接口来实现 。 代码如下: 产品类: <?php /** * 车子系列 * */ abstract Class BWM{ function __construct($pa) { } } Class BWM320 extends BWM{ function __construct($pa) { } } Class BMW523 extends BWM{ function __construc($pb){ } } 创建工厂类: /** * 创建工厂的接口 * */ interface FactoryBMW { function createBMW(); } /** * * 创建BWM320车 */ class FactoryBWM320 implements FactoryBMW { function createBMW($type){ return new BWM320(); } } /** * * 创建BWM523车 */ class FactoryBWM523 implements FactoryBMW { function createBMW($type){ return new BMW523(); } } 客户类: /** * * 客户得到车 */ class Customer { private $BMW; function getBMW($type){ switch ($type) { case 320: $BWM320 = new FactoryBWM320(); return $BWM320->createBMW(); case 523: $BWM523 = new FactoryBWM523(); return $BWM320->createBMW(); //.... } } } 可以看出工厂方法的加入,使得对象的数量成倍增长 。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的 。因为如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实 现 。 工厂方法小结: 工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口 。那我们是否一定要在代码中遍布工厂呢?大可不必 。也许在下面情况下你可以考虑使用工厂方法模式: 1)当客户程序不需要知道要使用对象的创建过程 。 简单工厂模式与工厂方法模式真正的避免了代码的改动了?没有 。在简单工厂模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判 断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样) 。而且产品对象创建条件的改变必然会引起工厂角色的修改 。 class Customer { private $BMW; function getBMW($type){ $class = new ReflectionClass('FactoryBWM' .$type );//建立 'FactoryBWM'这个类的反射类 $instance = $class->newInstanceArgs();//相当于实例化'FactoryBWM' .$type类 return $instance->createBMW(); //或者直接 /** * $instance = new 'FactoryBWM' .$type(); * return $instance->createBMW(); */ } } 六、抽象工厂模式随着客户的要求越来越高,宝马车需要配置空调 。于是这个工厂开始生产宝马车和配置需要的空调 。这时候工厂有二个系列的产品:宝马车和空调.宝马车必须使用对应的空调才能使用.这时候分别使用一个车工厂和一个空调工厂都不能满足我们的需求,我们必须确认车跟空调的对应关系 。因此把车工厂跟空调工厂联系在一起 。因此出现了抽象工厂模式 。 可以说,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上 。而且抽象工厂模式是三个里面最为抽象、最具一般性的 。 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件: 1)系统中有多个产品族,而系统一次只可能消费其中一族产品 。 抽象工厂模式的各个角色(和工厂方法一样): 1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关 。是具体工厂角色必须实现的接口或者必须继承的父类 。在java中它由抽象类或者接口来实现 。 其结构: 我们的例子: 代码: 产品类: <?php /** * 车子系列以及型号 * */ abstract class BWM{ } class BWM523 extends BWM { } class BWM320 extends BWM { } /** * 空调 * */ abstract class aircondition{ } class airconditionBWM320 extends aircondition { } class airconditionBWM52 extends aircondition { } 创建工厂类: /** * 创建工厂的接口 * */ interface FactoryBMW { function createBMW(); function createAirC(); } /** * * 创建BWM320车 */ class FactoryBWM320 implements FactoryBMW { function createBMW(){ return new BWM320(); } function createAirC(){ //空调 return new airconditionBWM320(); } } /** * * 创建BWM523车 */ class FactoryBWM523 implements FactoryBMW { function createBMW(){ return new BWM523(); } function createAirC(){ return new airconditionBWM523(); } } 客户: /** * * 客户得到车 */ class Customer { private $BMW; private $airC; function getBMW($type){ $class = new ReflectionClass('FactoryBWM' .$type );//建立 Person这个类的反射类 $instance = $class->newInstanceArgs();//相当于实例化Person 类 $this->BMW = $instance->createBMW(); $this->airC = $instance->createAirC(); } } 更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》 希望本文所述对大家PHP程序设计有所帮助 。 |