PHP版工厂模式,简单实用

ios开发求职招聘QQ群 http://www.cgia.cn/news/chuangyi/1647591.html
设计模式的六大原则

开闭原则:一个类、模块和函数应该对修改封闭,对扩展开放。

单一职责原则:一个类只做一件事,一个类应该只有一个引起它修改的原因。

里氏替换原则:子类应该可以完全替换父类。也就是说在使用继承时,只扩展新功能,而不要破坏父类原有的功能。

依赖倒置原则:细节应该依赖于抽象,抽象不应依赖于细节。把抽象层放在程序设计的高层,并保持稳定,程序的细节变化由底层的实现层来完成。

迪米特法则:又名「最少“知道”原则」,一个类不应知道自己操作的类的细节,换言之,只和朋友谈话,不和朋友的朋友谈话。

接口隔离原则:客户端不应依赖它不需要的接口。如果一个接口在实现时,部分方法由于冗余被客户端实现,则应该将接口拆分,让实现类只需依赖自己需要的接口方法。

所有的设计模式都是为了程序能更好地满足这六大原则。设计模式有很多种,大体分为三类。

一、构建型模式包含五种

工厂模式

抽象工厂模式

单例模式

建造型模式

原型模式

1、工厂模式

在平时写代码过程中,构建对象最常用的方式是new一个对象。这属于一种硬编码。每new一个对象,相当于调用者就知道了一个类,增加了类与类之间的联系,不利于程序的松耦合。其实构建过程可以被封装起来,工厂模式便是用于封装对象的设计模式。

1.1简单工厂模式例如:当我们需要一个苹果时,我们需要知道苹果的构造方法,需要一个梨子时,需要知道梨子的构造方法。更好的实现方式是有一个水果工厂,我们告诉工厂需要什么种类的水果,水果工厂将我们需要的水果制造出来给我们就可以了。这样我们就无需知道苹果、梨子是怎么种出来的,只用和水果工厂打交道即可。

将构建过程封装的好处不仅可以降低耦合,加入某个产品构造方法相当复杂,使用工厂模式可以大大减少代码重复。比如,如果生产一个苹果需要苹果种子、阳光、水分,将工厂修改如下:

调用者的代码则完全不需要变化,而且调用者不需要在每次需要苹果时,自己去构建苹果种子、阳光、水分以获得苹果。苹果的生产过程再复杂,也只是工厂的事。这就是封装的好处。

简单工厂模式就是让一个工厂类承担构建所有对象的职责。它的弊端也显而易见:

如果需要生产的产品过多,此模式会导致工厂类过于庞大,承担过多的职责,变成超级类。当苹果生产过程需要修改时,要来修改此工厂。梨子生产过程需要修改时,也要来修改此工厂。也就是说这个类不止一个引起修改的原因。违背了单一职责原则。

当要生产新的产品时,必须在工厂类中添加新的分支。而开闭原则:类应该对修改封闭。我们希望在添加新功能时,只需增加新的类,而不是修改既有的类,所以这就违背了开闭原则。

1.2工厂方法模式为了解决简单工厂模式的这两个弊端,工厂方法模式应运而生,它规定每个产品都有一个专属工厂。比如苹果有专属的苹果工厂,梨子有专属的梨子工厂。

这样和直接new出对象有什么区别?上文说工厂是为了减少类与类之间的耦合,让调用者尽可能少的和其他类打交道。用简单工厂模式,我们只需要知道FruitFactory,无需知道Apple、Pear类,很容易看出耦合度降低了。但用工厂方法模式,调用者虽然不需要和Apple、Pear类打交道了,但却需要和AppleFactory、PearFactory类打交道。有几种水果就需要知道几个工厂类,耦合度完全没有下降,甚至还增加了代码量!

工厂模式的第二个优点在工厂方法模式中还是存在的。当构建过程相当复杂时,工厂将构建过程封装起来,调用者可以很方便的直接使用,例:

调用者无需知道苹果的生产细节,当生产过程需要修改时也无需更改调用端。同时,工厂方法模式解决了简单工厂模式的两个弊端。

当生产的产品种类越来越多时,工厂类不会变成超级类。工厂类会越来越多,保持灵活。不会越来越大、变得臃肿。如果苹果的生产过程需要修改时,只需修改苹果工厂。梨子的生产过程需要修改时,只需修改梨子工厂。符合单一职责原则。

当需要生产新的产品时,无需更改既有的工厂,只需要添加新的工厂即可。保持了面向对象的可扩展性,符合开闭原则。

1.3抽象工厂模式工厂方法模式进一步优化

然后苹果工厂和梨子工厂都实现此接口:

此时,调用者可以将AppleFactory和PearFactory统一作为IFactory对象使用。

我们在创建时指定了具体的工厂类后,在使用时就无需再关心是哪个工厂类,只需要将此工厂当作抽象的IFactory接口使用。这种经过抽象的工厂方法模式被称作抽象工厂模式。

由于客户端只和IFactory打交道了,调用的是接口中的方法,使用时根本不需要知道是在哪个具体工厂中实现的这些方法,这就使得替换工厂变得非常容易。

我们把上面的苹果工厂替换成梨子工厂:

IFactory中只有一个抽象方法,这个是比较简单的工厂。实际上抽象工厂模式主要用于替换一系列方法。例如将程序中的SQLServer数据库整个替换为Access数据库,使用抽象方法模式的话,只需在IFactory接口中定义好增删改查四个方法,让SQLFactory和AccessFactory实现此接口,调用时直接使用IFactory中的抽象方法即可,调用者无需知道使用的什么数据库,我们就可以非常方便的整个替换程序的数据库,并且让客户端毫不知情。

抽象工厂模式很好的发挥了开闭原则、依赖倒置原则,但缺点是抽象工厂模式太重了,如果IFactory接口需要新增功能,则会影响到所有的具体工厂类。使用抽象工厂模式,替换具体工厂时只需更改一行代码,但要新增抽象方法则需要修改所有的具体工厂类。所以抽象工厂模式适用于增加同类工厂这样的横向扩展需求,不适合新增功能这样的纵向扩展。




转载请注明:http://www.aierlanlan.com/cyrz/7620.html