天天看點

JavaScript設計模式-政策模式

JavaScript設計模式-政策模式

    • 概念
    • 例子
    • 政策模式的優點
    • 政策模式的缺點
    • 總結
    • github倉庫位址:點選 [設計模式例子](https://github.com/fanhualuoye/design) 檢視

概念

  1. 多種途徑到達同一個目的地
  2. 現實中的例子:
  • 如果沒有時間但是不在乎錢,可以選擇坐飛機。
  • 如果沒有錢,可以選擇坐大巴或者火車。
  • 如果再窮一點,可以選擇騎自行車。
  1. 在程式設計中,我們也常常遇到類似的情況,要實作某一個功能有多種方案可以選擇。比如: 一個壓縮檔案的程式,既可以選擇 zip 算法,也可以選擇 gzip 算法。 這些算法靈活多樣,而且可以随意互相替換。這種解決方案就是政策模式。

例子

一個基于政策模式的程式至少由兩部分組成:

  1. 第一個部分是一組政策類,政策類封裝了具體的算法,并負責具體的計算過程。
  2. 第二個部分是環境類,接受客戶的請求,随後把請求委托給某一個政策類。
// 傳統寫法
        // 計算工資,performanceLevel評級、salary基本工資
        const getCalculateBonus = function (performanceLevel, salary) {
            if (performanceLevel === 'A') {
                return salary * 4
            }
            if (performanceLevel === 'B') {
                return salary * 3
            }
            if (performanceLevel === 'C') {
                return salary * 2
            }
        }
        getCalculateBonus('A', 20000) // 輸出:40000
        getCalculateBonus('B', 6000) // 輸出:24000

        //可以發現,這段代碼十分簡單,但是存在着顯而易見的缺點。
        // 1.calculateBonus 函數比較龐大,包含了很多 if-else 語句,這些語句需要覆寫所有的邏輯分支。
        // 2.calculateBonus 函數缺乏彈性,
        // 如果增加了一種新的績效等級 D,或者想把績效 A 的獎金系數改為 5,
        // 那我們必須深入 calculateBonus 函數的内部實作,這是違反開放封閉原則的。
        // 3.算法的複用性差,如果在程式的其他地方需要重用這些計算獎金的算法呢?我們的選擇隻有複制和粘貼。


        // 使用政策模式
        // 政策模式指的是定義一系列的算法,
        // 把它們一個個封裝起來。将不變的部分和變化的部分隔開是每個設計模式的主題,
        // 政策模式也不例外,政策模式的目的就是将算法的使用與算法的實作分離開來。

        // 這裡是算法的實作,strategies是以政策的集合
        const strategies = {
            'A': function (salary) {
                return salary * 4
            },
            'B': function (salary) {
                return salary * 3
            },
            'C': function (salary) {
                return salary * 2
            }
        }
        // 這裡是算法的使用
        const calculateBonus = function (level, salary) {
            return strategies[level](salary)
        }
        console.log(calculateBonus('A', 20000)) // 輸出:80000
        console.log(calculateBonus('B', 10000)) // 輸出:30000
        // 當我們想要添加新的類型,我們隻需要在strategies裡新增(修改)就可以了,而不用去改calculateBonus

        // 一個基于政策模式的程式至少由兩部分組成。
        // 第一個部分是一組政策類,政策類封裝了具體的算法,并負責具體的計算過程。
        // 第二個部分是環境類 Context,Context 接受客戶的請求,随後把請求委托給某一個政策類。

           

政策模式的優點

  1. 政策模式利用組合、委托和多态等技術和思想,可以有效地避免多重條件選擇語句。
  2. 政策模式提供了對開放—封閉原則的完美支援,将算法封裝在獨立的strategy 中,使得它們易于切換,易于了解,易于擴充。
  3. 政策模式中的算法也可以複用在系統的其他地方,進而避免許多重複的複粘貼工作。

    在政策模式中利用組合和委托來讓Context擁有執行算法的能力,這也是繼承的一種更輕便的替代方案。

政策模式的缺點

  1. 首先,使用政策模式會在程式中增加許多政策類或者政策對象,但實際上這比把它們負責的邏輯堆砌在 Context 中要好。
  2. 其次,要使用政策模式,必須了解所有的strategy,必須了解各個strategy 之間的不同點,這樣才能選擇一個合适的strategy。比如,我們要選擇一種合适的旅遊出行路線,必須先了解選擇飛機、火車、自行車等方案的細節。此時 strategy 要向客戶暴露它的所有實作,這是違反最少 知識原則的。

總結

定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。

github倉庫位址:點選 設計模式例子 檢視

繼續閱讀