前言:菜雞也有夢想,而我的夢想就是進一個真正的網際網路大廠。以前學習的時候沒有系統的整理,從今天開始要保持每週寫部落格的習慣,希望自己可以有所成長。為了培養程式設計思維,決定從設計模式開始寫起。我是通過讀《Javascript設計模式與開發實踐》來學習設計模式,並且將知識點和收穫記錄在部落格中。
此文僅記錄本人閱讀《JavaScript設計模式與開發實踐》的知識點與想法,感謝作者曾探大大寫出這麼好的一本書。如有冒犯,請聯絡本人:markcoder@outlook.com處理,請大家購買正版書籍。
1.職責鏈模式介紹
多個物件均有機會處理請求,從而解除傳送者和接受者之間的耦合關係。這些物件連線成為鏈式結構,每個節點轉發請求,直到有物件處理請求為止。
2.優缺點
2.1優點
1.可以根據需求變動,任意向責任鏈中新增或刪除節點物件
2.有固定的“開始節點”,可以從任意節點開始
2.2缺點
責任鏈最大的代價就是每個節點帶來的多餘消耗。當責任鏈過長,很多節點只有傳遞的作用,而不是真正地處理邏輯。
3.程式碼實現
在此使用書中的例子:公司針對支付過定金的使用者有一定的優惠政策。在正式購買後,已經支付過 500 元定金的使用者會收到 100 元的商城優惠券,200 元定金的使用者可以收到 50元的優惠券,而之前沒有支付定金的使用者只能進入普通購買模式,也就是沒有優惠券,且在庫存有限的情況下不一定保證能買到。
orderType:表示訂單型別(定金使用者或者普通購買使用者),code 的值為 1 的時候是 500 元 定金使用者,為 2 的時候是 200 元定金使用者,為 3 的時候是普通購買使用者。
pay:表示使用者是否已經支付定金,值為 true 或者 false, 雖然使用者已經下過 500 元定金的 訂單,但如果他一直沒有支付定金,現在只能降級進入普通購買模式。
stock:表示當前用於普通購買的手機庫存數量,已經支付過 500 元或者 200 元定金的用 戶不受此限制
let order500 = (orderType, pay, stock) => {
if (orderType === 1 && pay === true) {
console.log('500 元定金預購,得到 100 優惠券');
} else {
return 'nextSuccessor'; // 傳遞請求給下一個節點
}
}
let order200 = (orderType, pay, stock) => {
if (orderType === 2 && pay === true) {
console.log('200 元定金預購,得到 50 優惠券');
} else {
return 'nextSuccessor'; // 傳遞請求給下一個節點
}
}
let orderNormal = (orderType, pay, stock) => {
if (stock > 0) {
console.log( '普通購買,無優惠券' );
} else {
console.log( '庫存不足' );
}
}
class Chain {
constructor (fn) {
this.fn = fn;
this.successor = null;
}
setNextSuccessor (successor) {
return this.successor = successor;
}
passRequest () {
let ret = this.fn.apply(this, arguments);
if (ret === 'nextSuccessor') {
return this.successor && this.successor.passRequest.apply(this.successor, arguments);
}
return ret;
}
}
// 現在我們把 3 個訂單函式分別包裝成職責鏈的節點
let chainOrder500 = new Chain( order500 );
let chainOrder200 = new Chain( order200 );
let chainOrderNormal = new Chain( orderNormal );
// 然後指定節點在職責鏈中的順序
chainOrder500.setNextSuccessor( chainOrder200 );
chainOrder200.setNextSuccessor( chainOrderNormal );
chainOrder500.passRequest( 1, true, 500 ); // 輸出:500 元定金預購,得到 100 優惠券
chainOrder500.passRequest( 2, true, 500 ); // 輸出:200 元定金預購,得到 50 優惠券
chainOrder500.passRequest( 3, true, 500 ); // 輸出:普通購買,無優惠券
chainOrder500.passRequest( 1, false, 0 ); // 輸出:手機庫存不足
複製程式碼