工廠方法模式——給我一張名片
工廠方法模式:
- 通過對產(chǎn)品類的抽象使其創(chuàng)建業(yè)務觉既,主要負責用于創(chuàng)建多類產(chǎn)品的實例郎哭。
- 本意是說將實際創(chuàng)建對象工作推遲到子類當中.(在子類當中寫具體邏輯代碼蓖康,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()
安全的工廠方法
// 安全模式創(chuàng)建的工廠類
var Factory = fucntion(type, content) {
if(this instanceof Factory) {
var s = new this[type](content)
return s
} else {
return new Factory(type, content)
}
}
// 工廠原型中設置 創(chuàng)建所有類型數(shù)據(jù)對象 的基類
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類的原型里面注冊了一張名片,以后需要哪類直接拿著這張名片梆暮,查找這上面的信息就能找到這個類了(可以根據(jù)參數(shù)查找工廠的所需要的類)服协,不用擔心使用時找不到基類
- 可以輕松創(chuàng)建多個類的實例對象,避免使用者與對象類之間的耦合啦粹,用戶不必關心創(chuàng)建該對象的具體類偿荷,只需要調用工廠方法即可
抽象工廠模式——出現(xiàn)的都是幻覺
- 通過對類的工廠抽象使其業(yè)務用于對產(chǎn)品類簇的創(chuàng)建,而不負責創(chuàng)建某一類產(chǎn)品的實例
- 一般用抽象工廠模式作為父類來創(chuàng)建一些子類
示例代碼
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 {
// 拋出未創(chuàng)建抽象類的錯誤
throw new Error('為創(chuàng)建該抽象類')
}
}
// 小汽車抽象類
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('抽象方法不能調用贪嫂,只能重寫')
}
}
從上面代碼可以看出
- 抽象工廠其實是一個實現(xiàn)子類繼承父類的方法
- 在這個方法中我們需要通過傳遞子類以及要繼承父類(抽象類)的名稱
- 并且在抽象工廠方法中又增加了一次對抽象類存在性的一次判斷寺庄,如果存在,則將子類繼承父類的方法
- 然后子類通過寄生式繼承力崇,不過不是繼承父類的原型斗塘,而是通過new關鍵字復制父類的一個實例(這么做的原因是因為過渡類不應僅僅繼承父類的原型方法,還要繼承父類的對象屬性餐曹,所以要通過new關鍵字將父類的構造函數(shù)執(zhí)行一遍來復制構造函數(shù)中的屬性和方法)
- 對抽象工廠添加抽象類也很特殊逛拱,因為抽象工廠是個方法不需要實例化對象,所以只需要一份台猴,因此直接為抽象工廠添加類的屬性即可
使用方法
// 寶馬汽車類
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;
}
// 抽象工廠實現(xiàn)對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;
}
// 抽象工廠實現(xiàn)對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
自己這些代碼的過程中
- 抽象工廠方法的意義在于朽合,實現(xiàn)子類對父類(抽象類)的繼承,從而繼承抽象類的屬性和方法饱狂,對抽象類的方法進行重寫曹步,達到復用的目的
- 可以對多個抽象類進行封裝,能夠方便管理
- 和Java的抽象類達到比較相似的程度
由于更熟悉這個抽象工廠模式休讳,從而自己寫了幾次讲婚,所以更新的比較慢,見諒俊柔,主要是想要徹底熟悉了解這個抽象工廠方法
收獲:
- 抽象工廠模式是設計模式中最抽象的一種筹麸,也是創(chuàng)建模式中唯一一種抽象化創(chuàng)建模式活合。
- 該模式創(chuàng)建出的結果不是一個真實的對象實例,而是一個類簇(管理多個抽象類)物赶,它制定了類的結構
- 區(qū)別于 簡單工廠模式 創(chuàng)建單一對象白指, 工廠方式模式創(chuàng)建多累對象
- 由于JavaScript中不支持抽象化創(chuàng)建與虛擬方法,所以導致這種模式不能像其他面向對象語言中應用得那么廣泛