策略模式的思考

2021-08-30 05:19:16 字數 1646 閱讀 8472

大蝦們見笑了

這是小弟第一次寫這種文章

多多指點批評

在head first書中,作者用鴨子的例子來說明策略模式

起初,設計的模型是:有個基類duck,在基類定了了乙個變數:description,用來代表鴨子的外觀描述,還定義了乙個方法fly().

它的子類mallard(野鴨),sarcelle(綠翅鴨),scaup(白胸鴨)都繼承了基類中的變數和方法。

隨著業務的深入細化,鴨子需要增加新方法比如blat(),而其又出現了其他型別的鴨子,比如木鴨,塑料鴨,這些玩具鴨子不會fly,但可以blat

這時候就要面臨大面積的**重寫

首先:父類中增加了新方法就導致了所有的子類都面臨著變動。

其次:有些子類又不具備父類中的所有方法

這就和設計原則中的ocp原則發生了衝突

於是作者提出了策略模式

**進行了如下的重構:

首先把fly()方法提取出來,作為乙個單獨的介面ifly,同理blat()方法也作為單獨乙個介面iblat

根據鴨子的fly和blat行為分別寫實現類

然後在父類中增加2個變數,型別分別為iflay,iblat

子類顯示父類的fly()方式時,實際上沒有獨自定義方法,而是根據鴨子的型別呼叫ifly和iblat的不同實現

而其為了在執行中改變鴨子的行為,在鴨子子類中增加新2個改變fly和blat行為的方法。setfly(),setblat()

總結:雖然初始的設計存著問題。

1.子類必須實現父類的方法,各個子類的fly行為可能相同,這樣就無法達到**的重用了。

2.父類增加新的行為,所有的子類都需要變動

但是在策略模式中,問題2依舊存在,只不過不是給子類增加乙個方法,而是必須增加乙個新變數

個人感覺,策略模式的精髓在於,把子類中的方法提取出來作為乙個介面,與鴨子子類之間形成一種松耦合的關係

通過setfly()方法就可以在執行中動態地改變其行為。

書中說如果方法中存在著if-else這種判斷就應用策略模式,這樣說有點大,模糊了。反過來我們想想,如果我想在執行中動態

改變物件的行為,是如何實現的。

public void method(string type)else

}那麼我們就可以運用策略模式改寫

inte***ce imethod()

class methodone implements imethod()

}class methodtwo implements imethod()

}public class test()

public void setmethod(imethod imethod)

public void method()

public static void main(string args)}}

把判斷前後的處理方式提取成方法的好處就是解耦合,並達到**的重用

解耦合可以這樣理解,如果日後方法的處理方式又有了其他方式,我們就必須修改所有的子類,再增加一層判斷

利用策略模式,我們所要做的就是增加乙個新的實現類,這樣我的工作就大打減少了。而其**也容易維護了

這裡還有個原則,就是子類繼承父類的時候,最好不要增加新的方法,這樣子類向父類轉型的時候就容易丟失方法

如果說子類非要增加乙個父類中不存在的方法,那就需要重新審視自己的**了,看是否可以考慮使用組合關係

對策略模式與狀態模式的一點思考

在以前的一片博文裡 我發表了我對設計模式的一點看法 但是今天的乙個案例又讓我對設計模式又有了一點思考 今天在處理這麼乙個問題 元件a是我以前寫的,這個元件會不斷被重用,而今天要寫到的模組b用到了a,現在b有乙個很奇葩的需求,a似乎滿足不了了 怎麼辦?首先我想到的是能不能把問題簡單化,繞過這個問題 經...

策略模式 上下文與內部類的思考

策略模式一直程式開發中,最常用的模式之一 它的功能就是定義了一系列的演算法,這些演算法定義著公共的介面,所以它們之間可以相互替換。這使得我們在開發過程中,若有新的策略需要擴充套件時,程式變的很容易開發。下面是策略模式的結構示意圖 從結構示意圖中,我們能清楚的感受到,策略模式的巧妙之處就是將變化的東西...

日常解題策略思考

這幾天刷題的總結。乙個問題,先找到一般的解決問題的策略,由於時間和能力的關係,對特殊情況 corner case 及規律的把握不到位,就會導致更大的錯誤 可能 固化潛在的錯誤認知,這樣會加大回頭找漏洞時的難度 從最根本的地方來步步尋錯 當然不管想到或者選擇哪種,直至糾正的整個過程,對人分析和看待的問...