你知道javascript 中 abstract 仍是一個保留字,因此目前來講還不能像傳統面嚮對象語言那樣輕鬆地建立。抽象類是一種聲明但不能使用的類,當你使用就會報錯。不過javascript 是靈活的,因此咱們能夠在類的方法中手動地拋出錯誤來模擬抽象類。javascript
// 汽車抽象類,當使用其實例對象的方法時會拋出錯誤
var Car = function(){};
Car.prototype = {
getPrice : function(){
return new Error('抽象方法不能調用');
},
getSspeed : function(){
return new Error('抽象方法不能調用');
}
};
複製代碼
// 抽象工廠方法
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.Bus = function(){
this.type = type;
};
VehicleFactory.Bus.prototype = {
getPrice : function(){
return new Error('抽象的方法不能調用');
},
getPaggerNum : function(){
return new Error('抽象的方法不能調用');
}
}
// 貨車抽象類
VehicleFactory.Truck = function(){
this.type = 'truck';
};
VehicleFactory.Truck.prototype = {
getPrice : function(){
return new Error('抽象方法不能調用');
},
getTrainLoad : function(){
return new Error('抽象方法不能調用');
}
}
複製代碼
你能夠看到,抽象工廠類實際上是一個實現子類繼承父類的方法,在這個方法中,咱們須要經過傳遞子類以及要繼承父類(抽象類的名稱) 而且在抽象工廠方法中又增長了一次對抽象類存在性的一次判斷,若是存在,則將子類繼承父類的方法。而後子類經過寄生式繼承。繼承父類 的原型,而是經過 new 關鍵字複製父類的方法。而後子類經過寄生式繼承。繼承父類過程當中有一個地方須要注意,就是對過渡類的原型繼承時, 咱們不是繼承父類的原型方法,還要繼承父類的對象屬性,因此經過 new 關鍵字將父類的構造函數執行一遍來複制構造函數中的屬性和方法。 對抽象工廠添加抽象類也很特殊,由於抽象工廠是個方法不須要實例化對象,故只須要一份,所以直接爲抽象工廠添加類的屬性便可,因而咱們就 能夠經過點語法在抽象工廠上添加咱們一下子須要的三個汽車簇抽象類 Car, Bus, Truck. 聽我給你講一下,既然抽象工廠是用建立子類的(而本例中實際上是讓子類繼承父類,是對子類的一個拓展)咱們須要一些產品子類,而後讓子類繼承相應的產品簇抽象類java
// 寶馬汽車子類
var BMW = function(price, speed) {
this.price = price;
this.spped = speed;
}
// 抽象工廠實現對Car 抽象類的繼承
VehicleFactory(BMW, 'Car');
BMW.prototype.getPrice = function(){
return this.price;
}
BMW.prototype.getSpeed = function(){
return this.spped;
}
複製代碼
// 蘭博基尼汽車子類
var Lamborghini = function(price, speed){
this.price = price;
this.speed = speed;
}
// 抽象工廠實現對Car 抽象類的繼承
VehicleFactory(Lamborghini, 'Car');
Lamborghini.prototype.getPrice = function(){
return this.price;
}
Lamborghini.prototype.getSpeed = function(){
return this.speed;
}
複製代碼
// 宇通汽車子類
var YUTONG = function(price, passenger) {
this.price = price;
this.passenger = passenger;
}
// 抽象工廠實現對 Bus 抽象類的繼承
VehicleFactory(YUTONG, 'Bus');
YUTONG.prototype.getPrice = function() {
return this.price;
}
YUTONG.prototype.getPaggerNum = function() {
return this.passenger;
}
複製代碼
// 奔馳汽車子類
var BenzTruck = function(price, trainLoad) {
this.price = price;
this.trainLoad = trainLoad;
}
// 抽象工廠實現對 Truck 抽象類的繼承
VehicleFactory(BenzTruck, 'Truck')
BenzTruck.prototype.getPrice = function() {
return this.price;
}
BenzTruck.prototype.getTrainLoad = function() {
return this.price;
}
複製代碼
經過抽象工廠, 咱們就能知道每一個子類究竟是哪一類別了,而後他也具備了該類所必備的屬性和方法了。設計模式
var truck = new BenzTruck(100000, 1000);
console.log(truck.getPrice()); // 100000
console.log(truck.type); // truck
複製代碼
抽象工廠模式是設計模式中最爲抽象的一種,也是建立中惟一一種抽象化建立模式。該模式建立出的結果不是一個真實的對象實例,而是一個類簇,它制定了類的結構,這也就區別於簡單工廠模式建立單一對象,工廠方法模式建立多類對象。固然因爲Javascript中不支持抽象化建立於虛擬方法,因此致使這種模式不能向其餘面嚮對象語言中應用的那麼普遍。緩存