Strategy Pattern(策略模式)心得

  • 3263
  • 0
  • C#
  • 2008-11-29

一般來說策略模式最主要的重點在於

"把會變動的跟不會變動的部分區隔開"

區隔出來的部分應該要可以因應程式的運作

動態且合適的載入需要變動的那部份

cloudio最近在看的書的第一章也正好是在介紹這模式

一般來說策略模式最主要的重點在於

"把會變動的跟不會變動的部分區隔開"

在以物件導向撰寫程式時, 將變動的部份封裝是常用的技巧

而stragegy pattern是用來實現封裝的方法

by Allen提示

區隔出來的部分應該要可以因應程式的運作

動態且合適的載入需要變動的那部份

cloudio最近在看的書的第一章也正好是在介紹這模式

 

策略模式最常見的就是使用介面來做被切割會變動部分類別的一個規範

聽策略模式的命名大約可略知一二

在執行或coding階段依情況需求有策略的調整類別負責的行為

而在深入淺出設計模式中第一章節即是討論策略模式並用鴨子的飛行行為當作需要被封裝出來的部分

基本上運用的方式是將會變動的部分封裝成獨立的介面

再實作個別的類別繼承該介面而成為獨立出來的一群演算法已供需要調用的類別去合成它的實例

接著在超類別(父類別)中宣告該演算法的介面但先不實例它

以確保該介面負責的行為可以在子類別賦予實踐其他已繼承該介面並擁有其他行為的類別

那麼在設計繼承超類別的子類別中我們就可以去決定超類別中宣告的介面該實例出該演算法家族的哪個成員

也或者可以在超類別增加設定介面等於哪種行為的類別的方法

這樣就可以在程式執行階段改變設定介面該實例的類別以動態的改變行為

 

另外cloudio在網路上也發現了使用delegate委派來動態更改執行方法的方式

一樣類別可以先寫好,未來可以在擴充方法來調整程式在執行階段行為

因為感覺很不錯所以cloudio寫一段小範例來分享一下:D


class Program {

    static void Main(string[] args) {
        Duck duck = new Duck();
        duck.fly = new Fly(FlyNoWay);
        duck.DoFly();
        Console.ReadKey();
    }
    protected static string FlyWithWings() {
        return "I Can Fly @Q@";
    }
    protected static string FlyNoWay() {
        return "I Can't Fly @@";
    }
}

class Duck {
    public Fly fly;
    public void DoFly() {
        if (fly != null) {
            string FlyBehavior = fly();
            Console.WriteLine(FlyBehavior);
        }
    }
}

首先增加一個delegate型別,而這個delegate是為了傳遞方法給Duck類別用的

另外在Duck的類別中我們一樣宣告出該delegate出來並一樣不急著去建立它

再將該delegate設定為public這樣就可以在實例此類別時將delegate方法傳給類別中的delegate欄位

最後在增加一個DoFly的method去呼叫delegate這樣就大功告成了

 PS:strategy pattern並不會要求主要的class必需有父類別/子類別

只是cloudio提到的範例是這樣寫的

參考資料:

匿名委派範例

使用委派取代介面的時機 (C# 程式設計手冊)