【Javascript设计模式】第四课 幽灵工厂——抽象工厂模式
var Car = function(){};
Car.prototype = {
getPrice : function () {
throw new Error("抽象方法不能调用");
},
getSpeed : function () {
throw new Error("抽象方法不能调用");
}
};
var car = new Car();
car.getPrice();//Car is not defined
/*******************************************
* 抽象工厂模式
******************************************/
var VehicleFactory = function (subType, superType) {
//判断抽象工厂中是否有该抽象类
if(typeof VehicleFactory[superType] === 'function'){
//定义一个缓存类
function F(){};
//继承父类的属性和方法
F.prototype = new VehicleFactory[superType]();
//将子类constructor指向子类
subType.constructor = subType;
//子类原型继承父类
subType.prototype = new F();
}else{
throw new Error('未创建该抽象类');
}
}
//定义一个小汽车类
VehicleFactory.Car= function () {
this.type = 'car';
}
VehicleFactory.Car.prototype = {
getPrice : function(){
throw new Error('未创建该抽象类');
},
getSpeed : function () {
throw new Error('未创建该抽象类');
}
}
//定义一个公交车类
VehicleFactory.Bus= function () {
this.type = 'bus';
}
VehicleFactory.Bus.prototype = {
getPrice : function () {
throw new Error('未创建该抽象类');
},
getSpeed : function () {
throw new Error('未创建该抽象类');
}
}
var BMW = function (price, speed) {
this.price = price;
this.speed = speed;
}
VehicleFactory(BMW,'Car');
BMW.prototype.getPrice = function () {
return this.price;
}
BMW.prototype.getSpeed = function () {
return this.speed;
}
var bmw = new BMW(1000,100);
console.info(bmw.getSpeed());
console.info(bmw.getPrice());
三者的共同点是:
1、都有两种作用不同的类:产品类和工厂类。其中,工厂类在自己的方法中实例化产品类(即使用new命令生成产品类的对象),并将生成的产品类的对象提供给外部使用。
2、创建的过程,都是类似的:工厂类得到一个标志(可以由程序输入,也可以读取配置文件中的内容),返回一个产品对象。
三者的不同点:
1、简单工厂
简单工厂方法中,包括一个“抽象产品类”(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该“抽象产品类”的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。
简单工厂一般只包含一个具体的工厂类,由该工厂类生成所有的产品类的对象。生成产品类的方法,其内部一般是类似于switch的结构,根据输入的标志,选择创建不同类型的对象。由于不知道创建的对象到底是哪个类的,所以方法的返回值的类型是“抽象产品类”。
2、工厂方法
抽象工厂中,包括“抽象工厂类”和“抽象产品类”,同时包含不只一个工厂类。所有的工厂类都必须是“抽象工厂类”的子类,所有的产品都必须是“抽象产品类”的子类。
和简单工厂比起来,工厂方法一般是从抽象工厂开始的。一般都是在抽象工厂类中提供一个静态方法,由该方法根据输入的标志,生成不同的具体工厂类,然后由具体的产品类生成具体的产品。注意,一个具体工厂类只能生成一种具体的产品类的对象,不同的具体工厂生成不同的产品,而不是像简单工厂中那样,一个工厂类可以生成多种不同产品类的对象。可以这么理解,在选择不同的具体工厂类的时候,就选择了生成的产品,相对于简单工厂,相当于将选择产品的动作提前了。
因为不知道创建的具体工厂类到底是哪一个,所以生成具体工厂类的静态方法的返回值的类型是“抽象工厂类”。具体工厂类生成产品类的方法,返回值的类型也要求是“抽象产品类”(因为前端调用的时候,需要使用同样的代码来访问)。
3、抽象工厂
抽象工厂和工厂方法很类似,区别如下:
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个