about 1 year ago

本篇文章中,我們想要知道以下兩件事情 :

  1. 為什麼要使用它呢 ?
  2. 什麼是策略模式呢 ?

為什麼要使用策略模式呢 ?

我們簡單的寫一下,一個多需要用不同方法的登入方法,它可以選擇使用googlefacebook的方法,來進行登入。

var user = {
    login: function (type) {
        if (type == "google") {
            doGoogleLoginSomething();
            console.log("google login process");
        } else if (type == "facebook") {
            doFbLoginSomething();
            console.log("facebook login process");
        } else {
            doSomething();
            console.log("custom login process");
        }
    }
}


user.login("google");

那上面這段程式碼中,有那些缺點呢 ?

首先第一個,它包含了很多的 if else 判斷,這樣反而增加了該函數的邏輯分支。

第二個為該函數缺泛彈性,如果你想增加twitter的登入,那就必須修改這函數的內部實作,這樣違反了開放封閉原則

開放封閉原則 : 白話文就是當你增加新功能時,盡量不修改原有的程式碼。

好處 : 較好維護較好測試可重複使用

所以說,當碰到這種情況時,就可以使用策略模式囉 ~

策略模式簡單的來說,就是為了處理以下的情況 :

當使用者有相同的行為,但不同的場景時,有不同的方法。

例如 : 使用者想要進行登入,但我們可以使用googlefacebook等不同的方法來登入。

在白話文一點就是 : 當你有大量的if elseswitch就可以使用策略模式了。

策略模式是什麼 ?

接下來我們就要使用策略模式來修改上面的程式碼,但在開始前,我們要先知道策略模式是什麼。

簡單的說,它的定義如下 :

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

以我們上面登入的範例來看,login裡面的每一種登入方法就是一種演算法,但他都丟在裡面,所以我們策略模式就是要將他,一個一個封裝起來,並且可以相互的替換。

如下面的程式碼,我們將每一個登入的演算法都封裝起來,然後在需要那個的時後,就使用那個。

var user = {
    login: function (stragtegy) {
        stragtegy();
    }
}


var loginStrategy = {
    fb : function(){
        doFbLoginSomething();
    },
    google : function(){
        doGoogleLoginSomething();
    },
    custom : function(){
        doSomething();
    }
}

user.login(loginStrategy.fb);

首先我們先來看看可維護性,上面的程式碼中,我們假設要新增一個twitter,那你只需要在loginStrategy裡新增一個twitter的策略,這樣就不會動到主題的login函數,以防止,當你修改了login會影響到其它登入方法的問題。

再來來看看可測試性,我們只需要mock你要測試的策略,然後在將他丟到login裡面,進行測試,非常的簡單,如果是沒用策略模式的程式碼,我還真的要動腦想一下著麼寫單元測試了。

結論

上面我們簡單的用登入系統的例子,來說明策略模式,在 node 中,有一個叫passport js的東西,就是使用策略模式,來實作登入系統的實例,筆上之前就有寫過一篇關於 passport 的文章,可參考參考。

Passport.js 之 Hello 你好嗎 ~

參考資料

← Passport.js 之 Hello 你好嗎 ~ Socket 的哩哩扣扣 →
 
comments powered by Disqus