设计模式之一:工厂模式
1.简单工厂模式
对于自行车商店出售自行车:
- var BicycleShop = function(){};
- BicycleShop.prototype = {
- sellBicycle : function( model ){
- var bicycle;
- switch( model ){
- case "The Speedster":
- bicycle = new Speedster();
- break;
- case "The Lowrider":
- bicycle = new Lowrider();
- break;
- case "The Cruiser":
- default:
- bicycle = new Cruiser();
- break;
- }
- return bicycle;
- }
- }
- sellBicycle 方法根据所提供的自行车型号来进行自行车的实例创建。那么对于一家ABC店铺,需要Speedster车型我只需要
var ABC = new BicycleShop();
var myBike = ABC.sellBicycle("The Speedster");
以上方式很管用,但是一旦说我需要添加一些自行车款式的时候我就必须修改 BicycleShop 的 switch 部分,那么只要是修改就有可能带来BUG。所以,将这部分生成实例的代码单独的提出来分工交给一个简单的工厂对象是一个很不错的方法。
- var BicycleFactory = {
- createBicycle : function( model ){
- var bicycle;
- switch( model ){
- case "The Speedster":
- bicycle = new Speedster();
- break;
- case "The Lowrider":
- bicycle = new Lowrider();
- break;
- case "The Cruiser":
- default:
- bicycle = new Cruiser();
- break;
- }
- return bycicle;
- }
- }
BicycleFactory 是一个脱离于BicycleShop的单体。降低耦合度的效果显而易见。当需要添加新的类型的时候,不需要动 BicycleShop 只需修改工厂单体对象就可以。
- var BicycleShop = function(){};
- BicycleShop.prototype = {
- sellBicycle : function( model ){
- var bicycle = BicycleFactory.createBicycle(model);
- return bicycle;
- }
- }
以上就是一个很好的简单工厂模式的实例。该模式将成员对象的创建工作交给一个外部对象实现,该外部对象可以是一个简单的命名空间,也可以是一个类的实例。
2、工厂方法模式
是一种实现“工厂”概念的面上对象设计模式。实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
真正的工厂模式与简单工厂模式相比,主要区别就是它不是另外使用一个对象或者类来创建实例(自行车),而是使用一个子类。工厂是一个将其成员对象的实例化推迟到子类中进行的类。
比如加入BicycleShop可以决定从那一家厂商进行进货,那么简单的一个BicycleFactory是不够了的,因为各个厂商会各自生产不同的Speedster,Lowrider,Cruiser等型号自行车,所以首先需要生成各自厂商的shop实例,不同厂商的shop实例拥有不同的生成几个型号自行车的方法。
也就是相当于将自行车对象的实例化推迟到了shop实例中产生。
基础:
各自厂商:
那么接下来就很简单 对于来自 Acme 进货的
var acmeShop = new AcmeBicycleShop();
var newBicycle = acmeShop.sellBicycle("The Speedster");
当然,你也可以对于外层生成的子类实例在使用简单工厂模式进行包装一下~对于添加其他厂商也很简单,在创建一个Bicycle的子类重新定义其createBicycle的工厂方法即可。
比如加入BicycleShop可以决定从那一家厂商进行进货,那么简单的一个BicycleFactory是不够了的,因为各个厂商会各自生产不同的Speedster,Lowrider,Cruiser等型号自行车,所以首先需要生成各自厂商的shop实例,不同厂商的shop实例拥有不同的生成几个型号自行车的方法。
也就是相当于将自行车对象的实例化推迟到了shop实例中产生。
基础:
- var BicycleShop = function(){}
- BicycleShop.prototype={
- sellBicycle: function( model ){
- var bicycle = this.createBicycle( model );
- return bicycle;
- },
- createBicycle: function( model ){
- throw new Error( " Unsupported " );
- }
- }
各自厂商:
- var AcmeBicycleShop = function(){};
- extend( AcmeBicycleShop , BicycleShop );
- AcmeBicycleShop.prototype.createBicycle = function( model ){
- var bicycle;
- switch( model ){
- case "The Speedster":
- bicycle = new AcmeSpeedster();
- break;
- case "The Lowrider":
- bicycle = new AcmeLowrider();
- break;
- case "The Cruiser":
- default:
- bicycle = new AcmeCruiser();
- break;
- }
- return bicycle;
- }
- var GeneralBicycleShop = function(){};
- extend( GeneralBicycleShop , BicycleShop );
- GeneralBicycleShop.prototype.createBicycle = function( model ){
- ...
- }
那么接下来就很简单 对于来自 Acme 进货的
var acmeShop = new AcmeBicycleShop();
var newBicycle = acmeShop.sellBicycle("The Speedster");
当然,你也可以对于外层生成的子类实例在使用简单工厂模式进行包装一下~对于添加其他厂商也很简单,在创建一个Bicycle的子类重新定义其createBicycle的工厂方法即可。
三、抽象工厂模式
定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类
具体操作实际上是把工厂分为两层,第一个定义为一个工厂接口
然后定义工厂族(中国厂商:有生产各种自行车,美国厂商也有生产各种自行车)实现上面的工厂接口
然后调用时候我只需要传入一个抽象工厂,而无需指定具体是哪个厂商,返回一个厂商(即抽象工厂的返回值)
总结工厂的意义:把实例化对象的方法抽取出来,独立分装在每个工厂里面,与主程序进行解耦
依赖抽象原则的意义:
1.变量不要持有具体类的引用
2.不要让类继承自具体类,要继承抽象类或者接口
3.不要覆盖基类中已实现的方法
工厂模式使用场合
1. 动态实现
例如自行车的例子,创建一些用不同方式实现统一接口的对象,那么可以使用一个工厂方法或者简单工厂对象来简化实现过程。选择可以是明确进行的也可以是隐含的。
2. 节省设置开销
如果对象要进行复杂的并且彼此相关的设置的时候,那么工厂模式可以很显著的减少每种对象的代码量。将特定的设置代码提取出来会使得代码有极大地提升。并且能优化结构便于维护。
3. 用于许多小型对象组成一个大对象。
4. 工厂模式之利
主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字。将所有实例化的代码集中在一个位子防止代码重复。
5. 工厂模式之弊
大多数类最好使用new关键字和构造函数,可以让代码更加简单易读。而不必去查看工厂方法来知道。

浙公网安备 33010602011771号