JavaScript设计模式———抽象工厂模式
定义:
抽象工厂其实是实现子类继承父类的方法,只是一个方法。抽象工厂模式一般用在多人协作的超大型项目中,并且严格的要求项目以面向对象的思想进行完成。
简单工厂模式和工厂模式都是直接生产实例的,抽象工厂更像是生产工厂,其实抽象工厂其实是实现子类继承父类的方法。
说白了 抽象工厂模式 我认为就是工厂功能模式的扩充版
简单工厂生产实例 ,工厂功能模式生产实例的接口,抽象工厂生产的是工厂
抽象类
抽象类是一种声明但是不能使用的类,当使用时就会报错。
在JavaScript中,abstract还是一个保留字,不能像传统的面向对象语言那样轻松创建。
但是JavaScript是灵活的,可以在类的方法中手动地抛出错误来模拟抽象类。
如下:
var Car = function(){};
Car.prototype = {
getPrice:function () {
return new Error('抽象方法不能调用');
},
getSpeed:function () {
return new Error('抽象方法不能调用');
}
}
创建的car类什么都不能做,创建时没有任何属性,原型的方法也不能使用,但是在继承时很有用。因为父类定义了一些必要的方法,如果子类没有重写这些方法,那么调用时找到这些类就会报错。
当这些必要的方法从父类继承过来而没有具体去重写实现,那么实例化对象便会调用父类的这些方法,如果父类有友好提示,则对于忘记重写子类的错误的避免就会很有帮助。
抽象工厂模式
抽象工厂实际上是一个实现子类继承父类的,在这个方法中需要传递子类以及要继承父类的名称,并且在抽象工厂方法中增加了一次对抽象类存在性的一次判断,如果存在,则将子类继承父类的方法,然后子类通过寄生式继承。
抽象工厂方法
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 () {
return new Error('抽象方法不能调用');
},
getSpeed:function () {
return new Error('抽象方法不能调用');
}
}
//货车抽象类
VehicleFactory.Truck = function () {
this.type = 'Truck';
};
VehicleFactory.Truck.prototype = {
getPrice:function () {
return new Error('抽象方法不能调用');
},
getSpeed:function () {
return new Error('抽象方法不能调用');
}
}
抽象工厂实现对抽象类的继承
//宝马汽车子类
var BMW = function (price,speed) {
this.price = price;
this.speed = speed;
}
//抽象工厂实现对Car抽象类的继承
VehicleFactory(BMW,'Car');
BMW.prototype.getPrice = function () {
return this.price;
}
BMW.prototype.getSpeed = function () {
return this.speed;
}
//奔驰汽车子类
var BenzTruck = function(price,trainLoad){
this.price = price;
this.trainLoad = trainLoad;
}
//抽象工厂实现对Truck抽象类的继承
VehicleFactory(BenzTruck,'Truck')
BenzTruck.prototype.getPrice = function () {
return this.price;
}
BenzTruck.prototype.getTrained = function () {
return this.trainLoad;
}
通过抽象工厂,就知道每个子类到底是哪一种类别,然后它们也具有了该类所必备的属性和方法了。
测试:
//测试
var truck = new BenzTruck(1000,100);
console.log(truck.getPrice());//1000
console.log(truck.type);//Truck
var car = new BMW(10,5);
console.log(car.getPrice());//10
console.log(car.getSpeed());//5
总结
抽象工厂模式,它创建的结果不是一个对象,实现子类对"抽象类"(JavaScript没有抽象类,只是模拟抽象类)的继承,然后子类再自行实例化;
区分:
简单工厂模式:用于创建单一对象。
工厂方法模式:用于创建多类对象。
抽象工厂模式:用于创建抽象类簇。(用于产生不同产品的抽象类或者工厂类)