文章初衷
設計模式其實旨在解決語言本身存在的缺陷,
目前javaScript一些新的語法特性已經整合了一些設計模式的實現,
大家在寫程式碼的時候,沒必要為了用設計模式而去用設計模式,
那麼我這邊為什麼還寫設計模式的文章呢,
一方面是自己的一個整理,然後記錄出來,結合自己的理解,
一方面就是雖然語言特性本身已經實現這些模式,有了自己的語法,
但是我們何嘗不能去了解一下它是通過什麼樣的思路去實現了
在我看來設計模式更多的是讓我對於思考問題,有了一些更好的思路和想法
文章實現更多的表現為用一些簡單的案例,幫助大家去理解這樣的一種思路,
會存在故意把設計模式的實現往簡單的案例靠攏,
大家在真實專案中不要刻意去用設計模式實現相同的程式碼
設計模式在平時的一些程式碼中都會有所體現,大家也許經常用到,
耐心看文章,也許你會發現自己平時的程式碼就不斷在設計模式中體現
JavaScript設計模式系列
JavaScript設計模式系列,講述大概20-30種設計模式在JavaScript中的運用
後面對應的篇幅會陸續更新,歡迎大家提出建議
這是設計模式系列第二篇,講述建造者模式
注意
深入系列文章部分是有先後順序的,按照目錄結構順序閱讀效果最好。
勘誤及提問
如果有疑問或者發現錯誤,可以在相應的 issues 進行提問或勘誤。
如果喜歡或者有所啟發,歡迎 star,對作者也是一種鼓勵。
建造者模式
概念:
將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立
不同的表示。
不管扯淡的概念,上?,後面再反過頭來理解這句話
// #建造者模式
// 抽象建造者
var Car = function (param) {
// 速度
this.speed = param && param.speed || `0`;
// 重量
this.weight = param && param.weight || `0`;
}
Car.prototype = {
// 獲取速度
getSpeed: function () {
return this.speed;
},
// 獲取重量
getWeight: function () {
return this.weight
}
}
// 輪胎部件類
var Tyre = function (type) {
var that = this;
// 構造器
// 建構函式中通過傳入的type型別設定相對應的輪胎尺寸
(function (type,that) {
switch (type) {
case `small`:
that.tyre = `小號輪胎`;
that.tyreIntro = `正在使用小號輪胎`;
break;
case `normal`:
that.tyre = `中號輪胎`;
that.tyreIntro = `正在使用中號輪胎`;
break;
case `big`:
that.tyre = `大號輪胎`;
that.tyreIntro = `正在使用大號輪胎`;
break;
}
})(type,this);
}
Tyre.prototype = {
// 更換輪胎的方法
changeType: function (type) {
that.tyre = type;
that.tyreIntro = `正在使用`+type;
}
}
// 發動機部件類
var Engine = function (type) {
var that = this;
// 構造器
// 建構函式中通過傳入的type型別設定相對應的發動機型別
(function (type,that) {
switch (type) {
case `small`:
that.engine = `小號發動機`;
that.engineIntro = `正在使用小號發動機`;
break;
case `normal`:
that.engine = `中號發動機`;
that.engineIntro = `正在使用中號發動機`;
break;
case `big`:
that.engine = `大號發動機`;
that.engineIntro = `正在使用大號發動機`;
break;
}
})(type,this);
}
Engine.prototype = {
// 更換髮動機的方法
changeType: function (type) {
that.engine = type;
that.engineIntro = `正在使用`+type;
}
}
/**
* 指揮者,建造一個賓士車的類
* @param {*輪胎型別 small normal big} tyre
* @param {*發動機型別 small normal big} engine
* @param {*車輛基本屬性 param.speed:速度 param.weight: 重量} param
*/
var BenChi = function (tyre,engine,param) {
// 建立一個車輛快取物件
var _car = new Car(param);
// 建立車輛的輪胎
_car.tyreInfo = new Tyre(tyre);
// 建立車輛的發動機
_car.engineInfo = new Engine(engine);
// 將建立的車輛物件返回
return _car;
}
// 具體建造者 例項化賓士車類
var benchi1 = new BenChi(`small`,`big`,{speed: 200,weight: `200`});
console.log(benchi1.speed);// 200
console.log(benchi1.weight);// 200
console.log(benchi1.tyreInfo.tyre);// 小號輪胎
console.log(benchi1.tyreInfo.tyreIntro);// 正在使用小號輪胎
console.log(benchi1.engineInfo.engine);// 大號發動機
console.log(benchi1.engineInfo.engineIntro);// 正在使用大號發動機
// #建造者模式end複製程式碼
這段例子是這樣的意思,首先我們要建造一個車,
那麼車是一個比較複雜的東西,我們需要輪胎部件,發動機部件等等其他
複雜的部件,每個部件相對來說又是獨立的個體,又是具備很多獨立的行為
那麼針對這種複雜的物件(例子中是一輛車),我們把它分成一個個部件,
然後通過一系類的組裝,把這些部件都拼接在一起,組成一個複雜的物件,
這樣的方式就是建造者模式,一步步構建一個複雜的物件,
使用者只關心最後建造出來的車,不需要關心它具體的部件是如何實現的
建造者模式中存在的角色
這邊介紹一下建造者模式中存在的角色,方便大家去理解
- 抽象建造者
- 指揮者
- 具體建造者
結合上面的案例,我們去把案例中的情況根據角色去劃分一下,
這樣更好的去理解建造者模式
首先Car就是抽象建造者,它具備一些車的基本屬性還有方法,
它是抽象的,使用者不需要知道它的存在,
那麼Tyre(輪胎),Engine(發動機),分別就是車的具體部件(具體類),
建立的BenChi類,其實就是一個指揮者的角色,負責把對應的部件組裝起來,
具體建立一個什麼樣子的車,就是指揮者這邊決定的,
比如說這邊還有一個空調部件,有些車沒有的話,那麼指揮者在建立的時候,
就不需要加入這個部件,所以物件的建造都是指揮者這邊決定的
再下面就是具體建造者了,指揮者建立了一個賓士車的類,
那麼具體建造者,通過呼叫這個類去實現不同的車系,
比如賓士車它有很多系列,通過傳遞不同的引數,就可以建立不同的系列
這就是一個完整的建造者案例,把複雜物件簡單化,通過建造不同的部件類,
組成一個複雜的物件,不同的部件,在建立不同物件的時候,可以進行復用。
建造者模式的優點
-
在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
-
每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,使用者使用不同的具體建造者即可得到不同的產品物件。
-
可以更加精細地控制產品的建立過程。將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
-
增加新的具體建造者無須修改原有類庫的程式碼,指揮者類針對抽象建造者類程式設計,系統擴充套件方便,符合“開閉原則”。
建造者模式的缺點
- 建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
- 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
建造者模式的適用情況
-
需要生成的產品物件有複雜的內部結構,這些產品物件通常包含多個成員屬性。
-
隔離複雜物件的建立和使用,並使得相同的建立過程可以建立
不同的產品。
工廠模式與建造者模式的比較
- 與抽象工廠模式相比,建造者模式返回一個組裝好的完整產品,
而抽象工廠模式返回一系列相關的產品,這些產品位於不同的產品等級結構,構成了一個產品族。
- 在抽象工廠模式中,客戶端例項化工廠類,然後呼叫工廠方法獲取所需產品物件,而在建造者模式中,客戶端可以不直接呼叫建造者的相關方法,而是通過指揮者類來指導如何生成物件,包括物件的組裝過程和建造步驟,
它側重於一步步構造一個複雜物件,返回一個完整的物件。
- 如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,
那麼建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以返回一輛完整的汽車。
建造者模式的總結
-
建造者模式將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。建造者模式是一步一步建立一個複雜的物件,它允許使用者只通過指定複雜物件的型別和內容就可以構建它們,使用者不需要知道內部的具體構建細節。建造者模式屬於物件建立型模式。
-
建造者模式包含3個角色,抽象建造者建立物件的基本屬性方法,
指揮者用來組裝具體的部件,形成不同的物件,具體建造者負責實現指揮者建立的物件
最後我們再來理解建造者模式的概念就比較簡單了:
將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立
不同的表示。
注意
深入系列文章部分是有先後順序的,按照目錄結構順序閱讀效果最好。