狀態模式和策略模式的區別與聯繫?

設計模式的問題,最好能說的通俗些


@海公公 的回答很好。幾個關鍵點都說了。我只是來嚴肅地上個圖。

本質上講,策略模式和狀態模式做得是同一件事:去耦合。怎麼去耦合?就是把幹什麼(語境類)和怎麼干(策略介面)分開,互不依賴。打個比方,下面是我一天的行程:

class 我{
吃飯(){}
逛街(){}
啪啪啪(){}
睡覺(){}
}

但問題來了,啪啪啪是個技術活,有著名的48式,今天到底要用哪一式呢?於是我的代碼變成了這樣:

class 我{
吃飯(){}
逛街(){}
啪啪啪1式(){}
啪啪啪2式(){}
啪啪啪3式(){}
睡覺(){}
}

但代碼如果是這樣的,寶寶肯會被老闆開掉的。但寶寶發現,啪啪啪的方式其實取決於我的妹子。對三種不同類型的妹子,我的表現是不同的。

class 鬼妹 implements 妹子{
愛愛(){print("Come on!");}
}

class 乖妹 implements 妹子{
愛愛(){print("I love you!");}
}

class 萌妹 implements 妹子{
愛愛(){print("Ya Mie Die!");}
}

interface 妹子 {
愛愛();
}

而且我驚訝地發現,所有妹子都把啪啪啪叫做」愛愛「。所以只要我只要知道今天晚上是和哪個妹子在一起,根據多態性,我只要說同一句話:」妹子讓我們愛愛吧「。接下來發生的事,我只要閉上眼睛享受就好了。

class 我{
吃飯();
逛街();
啪啪啪(妹子 今晚的妹子){
今晚的妹子.愛愛();
}
睡覺();
}

於是,你懂的:

main(){
我 胖胖 = new 我();
print("周一:");
妹子 娘子 = new 乖妹();
胖胖.啪啪啪(娘子);
print("周二:");
妹子 小三 = new 萌妹();
胖胖.啪啪啪(小三);
}

//OutPut:
周一:I love you!
周二:Ya Mie Die!

以上的就叫:策略模式

但後來我發現,其實我做的每一件事都取決我的妹子,我徹底震驚了!我的生活不能沒有妹子!

class 我{
吃飯(妹子 今晚的妹子){
今晚的妹子.飯飯();
}
逛街(妹子 今晚的妹子){
今晚的妹子.逛逛();
}
啪啪啪(妹子 今晚的妹子){
今晚的妹子.愛愛();
}
睡覺(妹子 今晚的妹子){
今晚的妹子.呼呼();
}
}

於是終於說出了那句話:嫁給我吧!於是,她徹底走進了我的生活!

class 我{
吃飯(){
老婆.飯飯();
}
逛街(){
老婆.逛逛();
}
啪啪啪(){
老婆.愛愛();
}
睡覺(){
老婆.呼呼();
}

//fields
妹子 老婆 = new 乖妹子();
}

但你們是懂我的,我的小三怎麼辦呢?要是每天都能切換情人就最好了!

class 我{

切換情人(妹子 情人){
老婆 = 情人;
}

吃飯(){
老婆.飯飯();
}
逛街(){
老婆.逛逛();
}
啪啪啪(){
老婆.愛愛();
}
睡覺(){
老婆.呼呼();
}

//fields
妹子 老婆 = new 乖妹子();
}

於是每一天都充滿了新鮮感呢!

main(){
我 胖胖 = new 我();
print("周一:");
//老婆
胖胖.啪啪啪();
print("周二:");
妹子 小三 = new 萌妹();
胖胖.切換情人(小三);
//小三
胖胖.啪啪啪();
}

//OutPut:
周一:I love you!
周二:Ya Mie Die!

於是,我都愛上了這種叫」狀態模式「的生活方式。

所以,」策略模式「就好比單身的時候,沒有固定情人,每天用微信出去約泡。」狀態模式「就是結婚以後,有了固定的情人,生活可以在老婆和小三之間遊刃有餘!

說到這裡,大家一定都豁然開朗了吧!那麼,祝大家生活幸福!

-------------------------------------------------------

我的筆記棧 http://ciaoshen.com (筆記向,非教程)


update:

策略模式一般用於單個演算法,而狀態模式的每個狀態子類中需要包含所有原來的語境類(Context)中的所有方法的具體實現。

--------------------------------------------------------------------------------

通俗點講,也就不上代碼和UML圖了。

區別:

狀態模式將各個狀態所對應的操作分離開來,即對於不同的狀態,由不同的子類實現具體操作,不同狀態的切換由子類實現,當發現傳入參數不是自己這個狀態所對應的參數,則自己給Context類切換狀態;而策略模式是直接依賴注入到Context類的參數進行選擇策略,不存在切換狀態的操作。

聯繫:

狀態模式和策略模式都是為具有多種可能情形設計的模式,把不同的處理情形抽象為一個相同的介面,符合對擴展開放,對修改封閉的原則。

還有就是,策略模式更具有一般性一些,在實踐中,可以用策略模式來封裝幾乎任何類型的規則,只要在分析過程中聽到需要在不同實踐應用不同的業務規則,就可以考慮使用策略模式處理,在這點上策略模式是包含狀態模式的功能的,策略模式是一個重要的設計模式。


可以看看這個:Java中,狀態模式和策略模式的區別


推薦閱讀:

一個靜態類或者非靜態類,多個方法依賴一個函數,如何實現?
C++模版類如何動態獲取類型?
c++中如何正確實現克隆(原型)模式?
實現同一介面的不同類使用組合實現了多態,但是這破壞了DRY嗎?
設計模式在實際開發中用的多嗎?

TAG:iOS開發 | 設計模式 |