JS设计模式——工厂模式详解

它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器。取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型。

  • 简单工厂模式:使用一个类(通常为单体)来生成实例
  • 复杂工厂模式:使用子类来决定一个变量成员应该为哪个具体的类的实例.

简单工厂模式

var BicycleShop = function () { };
BicycleShop.prototype = {
  sellBicycle: function (model) {
    var bicycle;
    switch (model) {
      case "A"://A类型的自行车  
        bicycle = new A();
        break;
      case "B":
        bicycle = new B();
        break;
      case "C":
        bicycle = new C();
        break;
    }
    return bicycle;
  }
} 

以上方式很管用,但是如果需要添加一些自行车款式的时候,比如我想能生产D类型的自行车,这就需要修改BicycleShop的switch部分,这样就不太好了。


复杂工厂模式

为了和简单工厂形成对比,这里还是采用BicycleShop为例来说明工厂模式的设计理念。

我们打算让各个自行车商店自行决定从哪个生产厂家进货。鉴于此,单靠一个自行车工厂(BicycleFactory)是无法提供需要的所有的自行车的。 所以我们考虑将BicycleShop设计为一个抽象类,让子类根据各自的进货渠道实现其进货自行车(createBicycle)的工作:

var BicycleShop = function(){};
BicycleShop.prototype = {
    sellBicycle : function(model){
        //让其子类来完成这个工作
        var bicycle = this.createBicycle(model);
        return bicycle;
    },
    //抽象方法,必须实现后才能调用
    createBicycle : function(model){
        throw new Error("必须通过子类的实例才能调用此方法,进货自行车");
    }
};

BicycleShop类中定义了一个createBicycle方法,该方法一旦调用就会抛出异常,因此,该类是不能直接实例化的,该抽象类必须被继承,通过其子类来完成createBicycle的工作。

工厂模式实现

下面定义了两个子类,一个子类代表从Oracle公司进货的商店,一个子类代表从IBM公司进货的商店,代码如下:

//Oracle自行车商店
var OracleBicycleShop = function(){};
//继承父类
inherits(OracleBicycleShop,BicycleShop);
//实现createBicycle方法
OracleBicycleShop.prototype.createBicycle = function(model){
    var bicycle;
    //生产自行车
    switch(model){
        case "speedster":
            bicycle = new OracleSpeedster();
            break;
        case "lowrider":
            bicycle = new OracleLowrider();
            break;
        case "Alien":   
            bicycle = new OracleAlien();
            break;
        case "comfort cruiser":
        default :
            bicycle = new OracleComfortCruiser();
    }
    return bicycle;
};

//IBM自行车商店
var IBMBicycleShop = function(){};
//继承父类
inherits(IBMBicycleShop,BicycleShop);
//实现createBicycle方法
IBMBicycleShop.prototype.createBicycle = function(model){
    var bicycle;
    //生产自行车
    switch(model){
        case "speedster":
            bicycle = new IBMSpeedster();
            break;
        case "lowrider":
            bicycle = new IBMLowrider();
            break;
        case "Alien":   
            bicycle = new IBMleAlien();
            break;
        case "comfort cruiser":
        default :
            bicycle = new IBMComfortCruiser();
    }
    return bicycle;
};

经过这样的一个设计,就产生了专卖店的概念,OracleBicycleShop表示Oracle自行车专卖店,IBMBicycleShop则表示IBM自行车专卖店。现在,如果用户需要购买Speedster牌的自行车,无论跑到那个专卖店,都可以买到了,示例代码如下:

//到Oracle专卖店购买
var oracle = new OracleBicycleShop();
var yourNewBicycle = oracle.createBicycle("speedster");

//到IBM专卖店购买
var ibm = new IBMBicycleShop();
var myNewBicycle = ibm.createBicycle("speedster");

即便是要增加对其他生产厂家的支持,也是很简单的,只需要再创建一个BicycleShop的子类并实现其createBicycle方法即可。

根据不同的需求,对各个子类进行修改,以支持更多厂家其他型号的产品,这是工程设计模式最重要的特点。

 

posted @ 2018-06-06 17:43  狂奔的小马扎  阅读(12187)  评论(1编辑  收藏  举报