javascript设计模式——工厂模式

时间:2021-04-28 14:47:27

简单工厂模式

简单工厂模式会把创建工作交给外部去做。
使用一个工厂,您可以将该代码消减为一个函数调用。 从一个只包含单个函数的对象字面量开始。 在 JavaScript 中,一个对象字面量/单例就是一个简单工厂的构建方式。 在经典的面向对象编程语言中,这将是一个静态类。

比如下面创建一个汽车工厂,它包含的方法有创建汽车makeCar, 它接受的一个参数是一个字符串数组,该数组映射到不同的装饰者类。

var CarFactory = {
makeCar: function(features) {
var car = new Car();

// If they specified some features then add them
if (features && features.length) {
var i = 0,
l = features.length;

// iterate over all the features and add them
for (; i < l; i++) {
var feature = features[i];

switch(feature) {
case 'powerwindows':
car = new PowerWindowsDecorator(car);
break;
case 'powerlocks':
car = new PowerLocksDecorator(car);
break;
case 'ac':
car = new ACDecorator(car);
break;
}
}
}

return car;
}

}

如果我们要创建一个汽车的话,就很方便,就生成了一个新的汽车。

Var myCar = CarFactory.makeCar(['powerwindows', 'powerlocks', 'ac']);

复杂工厂模式

简单工厂模式会把创建工作交给外部的类来做,这实际上会增加类的数量,并不利于代码的组织。真正的工厂模式会把创建工作交给子类来完成,父类只对创建过程中的一般性问题进行处理,这些处理会影响到每个子类,而子类之间相互独立,可以对创建过程进行一些定制化操作。

对上面的进行改进, 例如,让我们假装有几个不同的汽车制造商,他们都有自己的店铺。 大部分情况下,所有店铺都利用同样的方法销售汽车,但他们制造不同的汽车。 因此,他们的方法都继承自相同的原型,但他们实施自己的制造流程。
下面定义一个抽象的类CarShop,他有sellCar和decorateCar。请注意, sellCar 调用 manufactureCar。这意味着 manufacturecar 需要被一个子类执行才能让你卖出一辆汽车。

/*定义一个抽象的类CarShop */
var CarShop = function(){};
CarShop.prototype = {
sellCar: function (type, features) {
var car = this.manufactureCar(type, features);

getMoney(); // make-believe function

return car;
},
decorateCar: function (car, features) {
/*
装饰车的方法和简单工厂模式相同
*/

},
manufactureCar: function (type, features) {
throw new Error("manufactureCar must be implemented by a subclass");
}
};

下面定义两个子类(子工厂)

* Subclass CarShop and create factory method */
var JoeCarShop = function() {};
JoeCarShop.prototype = new CarShop();
JoeCarShop.prototype.manufactureCar = function (type, features) {
var car;

// Create a different car depending on what type the user specified
switch(type) {
case 'sedan':
car = new JoeSedanCar();
break;
case 'hatchback':
car = new JoeHatchbackCar();
break;
case 'coupe':
default:
car = new JoeCoupeCar();
}

// Decorate the car with the specified features
return this.decorateCar(car, features);
};

/* Another CarShop and with factory method */
var ZimCarShop = function() {};
ZimCarShop.prototype = new CarShop();
ZimCarShop.prototype.manufactureCar = function (type, features) {
var car;

// Create a different car depending on what type the user specified
// These are all Zim brand
switch(type) {
case 'sedan':
car = new ZimSedanCar();
break;
case 'hatchback':
car = new ZimHatchbackCar();
break;
case 'coupe':
default:
car = new ZimCoupeCar();
}

// Decorate the car with the specified features
return this.decorateCar(car, features);
};

manufactureCar 方法是工厂方法。 工厂方法是父类的抽象,由子类实施,它的工作是创建对象(每个工厂方法创建的对象都具有相同的接口)。
以后如果要调用CarShop,就要调用它的子类

var carShop = new JoeCarShop();
var myCar = JoeCarShop.manufactureCar({ type: 'Car' },{features: ['powerwindows', 'powerlocks', 'ac']});

主要参考
http://www.adobe.com/cn/devnet/html5/articles/javascript-design-patterns-pt2-adapter-decorator-factory.html
https://segmentfault.com/a/1190000000491074