工廠方法模式——給我一張名片
工廠方法模式:
- 通過對產品類的抽象使其創建業務,主要負責用于創建多類產品的實例。
- 本意是說將實際創建對象工作推遲到子類當中.(在子類當中寫具體邏輯代碼,Java abstract 抽象類)
- Java?Script中將工廠方法看做一個實例化對象的工廠類
- 最好使用安全模式類,即給個類型的判斷(this instanceof 類)
安全模式
var Demo = function(){
if(!this instanceof Demo){
return new Demo()
}
}
Demo.prototype = {
show: function(){
console.log('獲取成功')
}
}
var d = Demo()
d.show()
安全的工廠方法
// 安全模式創建的工廠類
var Factory = fucntion(type, content) {
if(this instanceof Factory) {
var s = new this[type](content)
return s
} else {
return new Factory(type, content)
}
}
// 工廠原型中設置 創建所有類型數據對象 的基類
Factory.prototype = {
Java: function(content) {
// ......
},
JavaScript: function(content) {
// ......
},
UI: function(content) {
this.content = content;
(function(content){
var div = document.createElement('div');
div.innerHTML = content
div.style.border = '1px solid red'
document.getElementById('container').applendChild(div)
})(content)
},
php: function(content) {
// ......
}
}
工廠方法模式的好處
- 如果想添加其他類,不需要修改工廠類,而只需要在工廠類的原型里進行添加所需要的基類即可
- 好比你在Facroty類的原型里面注冊了一張名片,以后需要哪類直接拿著這張名片,查找這上面的信息就能找到這個類了(可以根據參數查找工廠的所需要的類),不用擔心使用時找不到基類
- 可以輕松創建多個類的實例對象,避免使用者與對象類之間的耦合,用戶不必關心創建該對象的具體類,只需要調用工廠方法即可
抽象工廠模式——出現的都是幻覺
- 通過對類的工廠抽象使其業務用于對產品類簇的創建,而不負責創建某一類產品的實例
- 一般用抽象工廠模式作為父類來創建一些子類
示例代碼
var VehicleFactory = function(subType, superType){
if(typeof VehicleFactory[superType] === 'function'){
// 緩存類
function F(){}
// 繼承父類的屬性和方法
F.prototype = new VehicleFactory[superType]()
// 將子類的constructor指向子類
subType.constuctor = 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 = 'bus'
}
VehicleFactory.Bus.prototype = {
getPrice: function(){
return new Error('抽象方法不能調用,只能重寫')
},
getPassengerNum: 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關鍵字將父類的構造函數執行一遍來復制構造函數中的屬性和方法)
- 對抽象工廠添加抽象類也很特殊,因為抽象工廠是個方法不需要實例化對象,所以只需要一份,因此直接為抽象工廠添加類的屬性即可
使用方法
// 寶馬汽車類
let 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
}
// 宇通汽車類
let YUTONG = function(price, passenger) {
this.price = price;
this.speed = passenger;
}
// 抽象工廠實現對Bus抽象類的繼承
VehicleFactory(YUTONG, 'Bus')
// 重寫抽象類的方法
YUTONG.prototype.getPrice = function(){
return this.price
}
YUTONG.prototype.getPassengerNum = function(){
return this.passenger
}
// 奔馳卡車類
let BenzTruck = function(price, trainload){
this.price = price;
this.trainload = trainload;
}
// 抽象工廠實現對Truck抽象類的繼承
VehicleFactory(BenzTruck, 'Truck')
// 重寫抽象類的方法
BenzTruck.prototype.getSpeed = function(){
return this.speed
}
BenzTruck.prototype.getTrainload = function(){
return this.trainload
}
// 實例化
let car = new BMW(200000, 100)
console.log(car.getPrice()) // 200000
console.log(car.type) // car
自己這些代碼的過程中
- 抽象工廠方法的意義在于,實現子類對父類(抽象類)的繼承,從而繼承抽象類的屬性和方法,對抽象類的方法進行重寫,達到復用的目的
- 可以對多個抽象類進行封裝,能夠方便管理
- 和Java的抽象類達到比較相似的程度
由于更熟悉這個抽象工廠模式,從而自己寫了幾次,所以更新的比較慢,見諒,主要是想要徹底熟悉了解這個抽象工廠方法
收獲:
- 抽象工廠模式是設計模式中最抽象的一種,也是創建模式中唯一一種抽象化創建模式。
- 該模式創建出的結果不是一個真實的對象實例,而是一個類簇(管理多個抽象類),它制定了類的結構
- 區別于 簡單工廠模式 創建單一對象, 工廠方式模式創建多累對象
- 由于JavaScript中不支持抽象化創建與虛擬方法,所以導致這種模式不能像其他面向對象語言中應用得那么廣泛