Javascript中Factory的应用

    这里拿Pro Javascript Design Pattern中的例子作为case。假如一家自行车店销售各种自行车: 

/*  The Bicycle interface.  */
var Bicycle =  new Interface("Bicycle", ["assemble", "wash", "ride", "repair"]);

/*  Speedster class.  */
var Speedster =  function () { }
Speedster.prototype = {
    assemble:  function () {
        console.log("Speedster Bicycle assembled.");
    },
    wash:  function () {
        console.log("Speedster Bicycle washed.");
    },
    ride:  function () {
        console.log("Speedster Bicycle ride.");
    },
    repair:  function () {
        console.log("Speedster Bicycle repaired.");
    }
};
Speedster.prototype.constructor = Speedster;

/*  Lowrider class.  */
var Lowrider =  function () { }
Lowrider.prototype = {
    assemble:  function () {
        console.log("Lowrider Bicycle assembled.");
    },
    wash:  function () {
        console.log("Lowrider Bicycle washed.");
    },
    ride:  function () {
        console.log("Lowrider Bicycle ride.");
    },
    repair:  function () {
        console.log("Lowrider Bicycle repaired.");
    }
};
Lowrider.prototype.constructor = Lowrider;

/*  ComfortCruiser class.  */
var ComfortCruiser =  function () { }
ComfortCruiser.prototype = {
    assemble:  function () {
        console.log("ComfortCruiser Bicycle assembled.");
    },
    wash:  function () {
        console.log("ComfortCruiser Bicycle washed.");
    },
    ride:  function () {
        console.log("ComfortCruiser Bicycle ride.");
    },
    repair:  function () {
        console.log("ComfortCruiser Bicycle repaired.");
    }
};
ComfortCruiser.prototype.constructor = ComfortCruiser;

/*  BicycleShop class.  */
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 Comfort Cruiser":
             default:
                bicycle =  new ComfortCruiser();
                 break;
        }

        Interface.ensureImplements(bicycle, [Bicycle]);
        bicycle.assemble();
        bicycle.wash();

         return bicycle;
    }
};
BicycleShop.prototype.constructor = BicycleShop;

/*  test  */
( function () {
     var bicycle =  new BicycleShop().sellBicycle("The Lowrider");
    bicycle.ride();
    bicycle.repair();

})(); 

其中,

Bicycle 为自行车接口,之后3个类为类型的自行车,在 BicycleShop 的SellBicycle中是先根据条件创建具体自行车型,然后组装清洗。 

 

 

    改进第一步是将上述SellBicycle方法利用Simple Factory进行改进: 

/*  Bicycle Factory  */
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 Comfort Cruiser":
             default:
                bicycle =  new ComfortCruiser();
                 break;
        }
        Interface.ensureImplements(bicycle, [Bicycle]);

         return bicycle;
    }
};

/*  BicycleShop class.  */
var BicycleShop =  function () { };
BicycleShop.prototype = {
    sellBicycle:  function (model) {
         var bicycle = BicycleFactory.createBicycle(model);
        bicycle.assemble();
        bicycle.wash();

         return bicycle;
    }
};

BicycleShop.prototype.constructor = BicycleShop; 

可以看到,多了一个Bicycle构造工厂, BicycleShop的职责只负责组装和清洗了。 当增加了新的车型,只需要更新BicycleFactory,不需要修改BicycleShop。

 

      好,当车型比较少时完全可以满足需要。但是,当车店需要区分品牌和车型时就不行了。我们继续,利用Factory Method来进行改进。因为改动较大,贴出完整代码如下: 

/*  The Bicycle interface.  */
var Bicycle =  new Interface("Bicycle", ["assemble", "wash", "ride", "repair"]);

/*  Acme Speedster class.  */
var AcmeSpeedster =  function () { }
AcmeSpeedster.prototype = {
    assemble:  function () {
        console.log("Acme Speedster Bicycle assembled.");
    },
    wash:  function () {
        console.log("Acme Speedster Bicycle washed.");
    },
    ride:  function () {
        console.log("Acme Speedster Bicycle ride.");
    },
    repair:  function () {
        console.log("Acme Speedster Bicycle repaired.");
    }
};
AcmeSpeedster.prototype.constructor = AcmeSpeedster;

/*  Acme Lowrider class.  */
var AcmeLowrider =  function () { }
AcmeLowrider.prototype = {
    assemble:  function () {
        console.log("Acme Lowrider Bicycle assembled.");
    },
    wash:  function () {
        console.log("Acme Lowrider Bicycle washed.");
    },
    ride:  function () {
        console.log("Acme Lowrider Bicycle ride.");
    },
    repair:  function () {
        console.log("Acme Lowrider Bicycle repaired.");
    }
};
AcmeLowrider.prototype.constructor = AcmeLowrider;

/*  Acme ComfortCruiser class.  */
var AcmeComfortCruiser =  function () { }
AcmeComfortCruiser.prototype = {
    assemble:  function () {
        console.log("Acme ComfortCruiser Bicycle assembled.");
    },
    wash:  function () {
        console.log("Acme ComfortCruiser Bicycle washed.");
    },
    ride:  function () {
        console.log("Acme ComfortCruiser Bicycle ride.");
    },
    repair:  function () {
        console.log("Acme ComfortCruiser Bicycle repaired.");
    }
};
AcmeComfortCruiser.prototype.constructor = AcmeComfortCruiser;


/*  General Speedster class.  */
var GeneralSpeedster =  function () { }
GeneralSpeedster.prototype = {
    assemble:  function () {
        console.log("General Speedster Bicycle assembled.");
    },
    wash:  function () {
        console.log("General Speedster Bicycle washed.");
    },
    ride:  function () {
        console.log("General Speedster Bicycle ride.");
    },
    repair:  function () {
        console.log("General Speedster Bicycle repaired.");
    }
};
GeneralSpeedster.prototype.constructor = GeneralSpeedster;

/*  General Lowrider class.  */
var GeneralLowrider =  function () { }
GeneralLowrider.prototype = {
    assemble:  function () {
        console.log("General Lowrider Bicycle assembled.");
    },
    wash:  function () {
        console.log("General Lowrider Bicycle washed.");
    },
    ride:  function () {
        console.log("General Lowrider Bicycle ride.");
    },
    repair:  function () {
        console.log("General Lowrider Bicycle repaired.");
    }
};
GeneralLowrider.prototype.constructor = GeneralLowrider;

/*  General ComfortCruiser class.  */
var GeneralComfortCruiser =  function () { }
GeneralComfortCruiser.prototype = {
    assemble:  function () {
        console.log("General ComfortCruiser Bicycle assembled.");
    },
    wash:  function () {
        console.log("General ComfortCruiser Bicycle washed.");
    },
    ride:  function () {
        console.log("General ComfortCruiser Bicycle ride.");
    },
    repair:  function () {
        console.log("General ComfortCruiser Bicycle repaired.");
    }
};
GeneralComfortCruiser.prototype.constructor = GeneralComfortCruiser;


/*  BicycleShop class.  */
var BicycleShop =  function () { };
BicycleShop.prototype = {
    sellBicycle:  function (model) {
         var bicycle =  this.createBicycle(model);
        bicycle.assemble();
        bicycle.wash();

         return bicycle;
    },
    createBicycle:  function (model) {
         throw  new Error("BicycleShop is abstract, not implements createBicycle.");
    }
};
BicycleShop.prototype.constructor = BicycleShop;

/*  Acme Bicycle Shop  */
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 Comfort Cruiser":
         default:
            bicycle =  new AcmeComfortCruiser();
             break;
    }
    Interface.ensureImplements(bicycle, [Bicycle]);

     return bicycle;
};


/*  General Bicycle Shop  */
var GeneralBicycleShop =  function () { };
extend(GeneralBicycleShop, BicycleShop);
GeneralBicycleShop.prototype.createBicycle =  function (model) {
     var bicycle;
     switch (model) {
         case "The Speedster":
            bicycle =  new GeneralSpeedster();
             break;
         case "The Lowrider":
            bicycle =  new GeneralLowrider();
             break;
         case "The Comfort Cruiser":
         default:
            bicycle =  new GeneralComfortCruiser();
             break;
    }
    Interface.ensureImplements(bicycle, [Bicycle]);

     return bicycle;
};


/*  test  */
( function () {
     var bicycle =  new GeneralBicycleShop().sellBicycle("The Lowrider");
    bicycle.ride();
    bicycle.repair();

})();  

重点在于,我们将

BicycleShop变更为一个抽象类,即将CreateBicycle()方法作为抽象方法。然后,
AcmeBicycleShop 和 
GeneralBicycleShop作为2个品牌的自行车店均继承于它,各自实现CreateBicycle()方法。

 

另外,附件还附有2个例子,download 

 

 

 

你可能感兴趣的:(JavaScript)