有一天...
被問了一個問題,在實作登入功能時,如果要支援不同的登入方式(ex: FB/google/twitter),那麼該使用Strategy Pattern還是Command Pattern?
對於design pattern本身就不算瞭解,被問到這問題真的是完全無法解釋。開始了漫長的辜狗之旅,但看了一串又一串的討論還是無法解釋之後,決定配合字面定義來看:
COMMAND: 命令
命令通常有—發號命令者、接受命令者(負責決定如何執行)、命令、命令執行對象。比如說Gwen叫Howie去打掃(家裡),Gwen是發號命令者,命令的內容有 1.任務:打掃 2.任務執行者:Howie 3.任務對象:家裡。發號命令者可以決定他要執行什麼命令,對誰執行或是更改任務。比如說Gwen也可以選擇要他家的貓Uno去打掃(變更接受命令者),或是Gwen可以叫Howie去打掃隔壁老王的家(更變執行對象),又或是可以叫Howie把家裡重新裝潢一次(變更任務)。
STRATEGY: 策略
根據形勢發展而制定的行動方針或方法,目的是完成一個明確的任務。策略說的是不同物件(形勢發展),執行同樣的動作時(如前例:打掃家裡),會採取不同的路徑(行動方針,策略)。之前的例子用策略的角度來看就是:同樣是打掃,Howie與Uno打掃的方式就完全不一樣(實際上,Uno是一隻貓)
我們來看一下Wiki上面對於Command & Strategy的design pattern的解說:
Command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time.
Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable.
還是不太懂?
Command pattern強調的是發號命令者
、接受命令者
、命令
、命令執行對象
之間的關係,command本身只是一個資訊傳遞的載體,負責把發號命令者的命令傳遞給接受者。而Strategy pattern是用來讓單一任務可以有不同的解法。
回到登入的問題,假設我們系統需要提供使用者FB/twitter/google三種不同帳號登入,那麼我們該用command還是strategy?
如果我們用command pattern,那麼我們需要一種命令:登入,而命令執行者有三個:FB登入小幫手、twitter登入小幫手以及google登入小幫手。如果是用strategy pattern的話,我們需要三種不同的策略:FB登入/twitter登入/google登入。
這裡就會發現,就算登入的方式變得再怎麼多種,命令還是只有一種,只是一直增加不同的命令執行者。當然我們可以把命令變成三種:登入FB/登入twitter/登入google,然後再用三個命令執行者來處理這三種命令(考量到command pattern裡的command其實只負責資訊的傳遞,任務的處理還是需要由命令執行者來做),但這樣子似乎又有點過度分工。前面的敘述可以知道command pattern裡面的command儲存了三個面向的資料:1.任務 2.誰執行 3.對誰執行,而在實作登入功能時其實有兩個是不需要的:1.任務
:很單純的就是登入 3.執行的對象
是系統也不會變動,唯一會變的就是不同的命令執行者而已。
而如果是用strategy pattern的話,在實作時則是寫好各種不同的登入strategy,再依照使用者的選擇呼叫相對應的strategy來處理即可。依照這樣的分析下來,不同的登入方式應該用strategy pattern即可解決,也因此,passportjs用的是strategy pattern。
沒有留言:
張貼留言