Javascript設計模式之職責鏈模式

擼狗吸貓發表於2019-05-07

前言:菜雞也有夢想,而我的夢想就是進一個真正的網際網路大廠。以前學習的時候沒有系統的整理,從今天開始要保持每週寫部落格的習慣,希望自己可以有所成長。為了培養程式設計思維,決定從設計模式開始寫起。我是通過讀《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 ); // 輸出:手機庫存不足
複製程式碼

相關文章