設計模式之旅-策略者模式(組合模式)

序言

情景設計

設計一款模擬鴨子的遊戲,遊戲中出現各種鴨子,一邊游泳戲水,一邊呱呱叫。所用的鴨子會呱呱叫,也會游泳,所以基類負責實現。但是每一款鴨子外觀不一樣,所以這是抽象行爲。由子類實現。

  1. 前期設計及思路
    根據情景的設計,首先我們想到這是一些列的鴨子,便會想到利用繼承的手段,進行解決。其UML圖型爲:
    這裏寫圖片描述
    後續設計:需要讓有的鴨子飛,有的鴨子不能飛。

  2. 後續設計
    問題:
    1、在調用中是通過抽象類進行操作的,所以新功能在超類有所體現,
    但是下載超類中實現,就所有的鴨子會飛。
    2、在超類中是飛的行爲是抽象函數,這樣每個子類都要實現,代碼重寫太複雜。
    3、用接口,只讓飛的鴨子繼承實現飛的行爲接口,這樣在超類中進行初始化接口。
    4、但是用接口後,讓飛的行爲進行修改,那個每個子類中飛的行爲也要修改,這樣改動也是很大。
    經過分析,利用組合的原則,將變化部分進行提取,封裝一個新類,所以我們見fly這個行爲提取出來,行爲上肯定是接口,同時這個接口由行爲類實現,而不是具體鴨子類實現,這樣就實現策略模式。
    這裏的接口就是所謂的概念,針對“利用接口編程”,關鍵在於多態。利用多態,程序可以對超類進行操作,根據實際情況執行到真正行爲,將行爲和對象進行解耦。
    在程序運行時就是針對超類編程,超類編程就是接口和抽象類。
    圖爲:這裏寫圖片描述
    所以這樣針對新行爲,我們重新定義個接口,然後實現這個接口,在調用時初始化接口。
    其中主要的代碼爲:

//關鍵這是超類,必定是抽象類
public abstract class Duck
{
     protected IFlyBehavior flyBehavior;

     protected QuackBehavior quackBehavior; 

    public virtual void Quack()
    {
        throw new System.NotImplementedException();
    }
    //當然這些行爲也可通過接口,但是這游泳鴨子都會,所以超類直接實現
    public virtual void Swim()
    {
        throw new System.NotImplementedException();
    }
  //抽象函數,子類必須實現,意味子類這個行爲不同
   public abstract void DisPlay();

    public virtual void performFly()
    {
    //通過接口執行fly行爲,要尋找接口在那初始化
        flyBehavior.fly();
    }

}
//duck的子類,其中初始化了接口
public class BlueDuck : Duck
{
    public BlueDuck()
    {
    //初始化接口,在用BlueDuck初始化Duck時,接口也被初始化了。
        flyBehavior = new FlyWithWings();
    }
    public override void DisPlay()
    {
        throw new System.NotImplementedException();
    }
}

總結

當你將兩個類結合起來使用時,如同本例,這就是組合。這種做法的不同是在於行爲不是繼承而來,單獨通過行爲類和接口進行實現。
策略模式定義了算法族,分別封裝起來,讓他們之間可以相互替換,使算法的變化獨立於使用算法的客戶。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章