摘要:書籍建造者類調用建造者高效能人士的七個習慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內容設計模式張容銘
1 什么是建造者模式?
建造者模式(Builder)是將一個復雜對象的構建層與其表示層相互分離,同樣的構建過程可采用不同的表示。
建造者模式的特點是分步構建一個復雜的對象,可以用不同組合或順序建造出不同意義的對象,通常使用者并不需要知道建造的細節,通常使用鏈式調用來進行建造過程,最后調用build方法來生成最終對象。
同樣作為創建型的設計模式,需要注意和工廠模式的區別,工廠雖然也是創建對象,但怎樣創建無所謂,工廠模式關注的是創建的結果;而建造者模式不僅得到了結果,同時也參與了創建的具體過程,適合用來創建一個復雜的復合對象。
2 ES6中的建造者模式下面我們來假設一個出版社的書籍后臺錄入系統的業務場景,書籍有四個必填信息,分別是:書名,作者,價格,分類;我們希望創建一個書籍對象返回給后端。下面我們來一步一步深入使用ES6的語法結合建造者模式創建對象。
//書籍建造者類 class BookBuilder { constructor() { this.name = ""; this.author = ""; this.price = 0; this.category = ""; } withName(name) { this.name = name; return this; } withAuthor(author) { this.author = author; return this; } withPrice(price) { this.price = price; return this; } withCategory(category) { this.category = category; return this; } build() { return { name: this.name, author: this.author, prices: this.price, category: this.category } } } //調用建造者類 const book = new BookBuilder() .withName("高效能人士的七個習慣") .withAuthor("史蒂芬·柯維") .withPrice(51) .withCategory("勵志") .build();
上面就通過我BookBuilder這個創建者類的寫法和調用方法,但是僅僅是一個4個屬性的對象,我們使用了如此多的代碼去創建,這遠比直接在constructor傳遞參數創建對象要復雜得多。這是由于在創建的過程中,我們有太多的withxxxx方法。我們其實可以自動創建這類withxxxx方法以簡化代碼。
//書籍建造者類 class BookBuilder { constructor() { this.name = ""; this.author = ""; this.price = 0; this.category = ""; Object.keys(this).forEach(key => { const withName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`; this[withName] = value => { this[key] = value; return this; } }) } //調用建造者 build() { const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== "function"); return keysNoWithers.reduce((returnValue, key) => { return { ...returnValue, [key]: this[key] } }, {}) } } const book = new BookBuilder() .withName("高效能人士的七個習慣") .withAuthor("史蒂芬·柯維") .withPrice(51) .withCategory("勵志") .build();
上面的BookBuilder這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。我們將所有的建造方法withxxxx在constructor調用時自動被創建,這里我們使用了一些ES6的新語法:Object.keys獲取對象屬性數組,...的合并對象的語法。
雖然該寫法在閱讀起來會比第一個方法難以理解,但是這樣寫法的真正作用在于,當我們需要許多的建造者類時,我們可以將上面自動創建withxxx和build的代碼提取為一個父類。在創建其他建造者類時繼承該父類,這使得在創建多個建造者類時變得十分容易。
//父類 class BaseBuilder { init() { Object.keys(this).forEach(key => { const withName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`; this[withName] = value => { this[key] = value; return this; } }) } build() { const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== "function"); return keysNoWithers.reduce((returnValue, key) => { return { ...returnValue, [key]: this[key] } }, {}) } } //子類1: 書籍建造者類 class BookBuilder extends BaseBuilder { constructor() { super(); this.name = ""; this.author = ""; this.price = 0; this.category = ""; super.init(); } } //子類2: 印刷廠建造者類 class printHouseBuilder extends BaseBuilder { constructor() { super(); this.name = ""; this.location = ""; this.quality = ""; super.init(); } } //調用書籍建造者類 const book = new BookBuilder() .withName("高效能人士的七個習慣") .withAuthor("史蒂芬·柯維") .withPrice(51) .withCategory("勵志") .build(); //調用印刷廠建造類 const printHouse = new printHouseBuilder() .withName("新華印刷廠") .withLocation("北京海淀區") .withQuality("A") .build();總結
在之前提到的幾種工廠模式中,他們都有一個共同特點,就是對象的創建過程不得而知,我們在調用一個函數后返回了最終的結果對象。但是在創建者模式中我們關心的是對象的創建過程,我們通常將創建復雜對象的各個類模塊化,在ES6中,我們采用import和export的語法可以很靈活的引用和導出這些模塊進行我們的建造模式最終生成一個結果對象。
可以看出,建造者模式的使用有且只適合創建極為復雜的對象。在前端的實際業務中,在沒有這類極為復雜的對象的創建時,還是應該直接使用對象字面或工廠模式等方式創建對象。
參考內容:
[1] An Exploration of JavaScript Builders —— Ryan Oglesby
[2] 《 JavaScript設計模式 》—— 張容銘
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/113424.html
摘要:書籍建造者類調用建造者高效能人士的七個習慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內容設計模式張容銘 showImg(https://segmentfault.com/img/remote/1460000015147692); 1 什么是建造者模式? 建造者模式(Builder)是將一個復雜對象的構建層與其表...
摘要:優點建造者模式的封裝性很好,對象本身與構建過程解耦。建造者模式很容易進行擴展。適用場景需要生成的對象具有復雜得內部結構且內部屬性本身相互依賴建造者模式的代碼實現建造者模式主要有個部分產品類建造者類指揮者類客戶。建造者完成相應的部分。 建造者模式 建造者模式(builder pattern)比較簡單,它屬于創建型模式的一種,將一個復雜的對象分解成多個簡單的對象來進行構建,將復雜的構建層與...
摘要:注意事項聲明函數時候處理業務邏輯區分和單例的區別,配合單例實現初始化構造函數大寫字母開頭推薦注意的成本。簡單工廠模式使用一個類通常為單體來生成實例。 @(書籍閱讀)[JavaScript, 設計模式] 常見設計模式 一直對設計模式不太懂,花了一下午加一晚上的時間,好好的看了看各種設計模式,并總結了一下。 設計模式簡介 設計模式概念解讀 設計模式的發展與在JavaScript中的應用 ...
摘要:什么是裝飾器模式向一個現有的對象添加新的功能,同時又不改變其結構的設計模式被稱為裝飾器模式,它是作為現有的類的一個包裝。中的裝飾器模式中有一個的提案,使用一個以開頭的函數對中的及其屬性方法進行修飾。 1 什么是裝飾器模式 showImg(https://segmentfault.com/img/remote/1460000015970102?w=1127&h=563); 向一個現有的對...
閱讀 3637·2021-11-19 09:40
閱讀 3095·2019-08-30 15:54
閱讀 2313·2019-08-30 15:44
閱讀 3196·2019-08-29 15:35
閱讀 3331·2019-08-29 12:22
閱讀 2861·2019-08-28 18:01
閱讀 3140·2019-08-26 13:54
閱讀 902·2019-08-26 12:24