首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Head First 設計模式筆記:策略模式與鴨子模擬器(C# 實作)

     編輯:關於C語言

策略模式(Strategy Pattern)是行為型設計模式的經典入門,核心在於「將變化的演算法封裝成可互換的策略類,讓客戶端動態切換行為」。《Head First 設計模式》以鴨子模擬器為例,生動展示了「組合優於繼承」、「針對介面程式設計」兩大原則。

設計原則回顧

  1. 找出會變化的部分,封裝起來,與不變部分分離
  2. 針對介面(Interface)程式設計,而非具體類別
  3. 多用組合(Composition),少用繼承(Inheritance)

問題場景:鴨子行為多樣化

基底 Duck 類別有四種行為:

  • display():外觀顯示,各子類別不同 → 抽象方法
  • swim():游泳,所有鴨子相同 → 基底類別實作
  • fly():飛行,橡皮鴨不會飛 → 提取為介面
  • quack():叫聲,橡皮鴨吱吱叫、木頭鴨不叫 → 提取為介面

介面與策略類別設計

飛行行為介面與實作

public interface FlyBehavior { string Fly(); }

public class FlyWithWings : FlyBehavior {
    public string Fly() => "正在用翅膀飛行";
}

public class FlyNoWay : FlyBehavior {
    public string Fly() => "不會飛";
}

叫聲行為介面與實作

public interface QuackBehavior { string Quack(); }

public class Quack : QuackBehavior {
    public string Quack() => "嘎嘎叫";
}

public class Squeak : QuackBehavior {
    public string Quack() => "吱吱叫";
}

public class MuteQuack : QuackBehavior {
    public string Quack() => "不會叫";
}

鴨子基底類別:組合策略物件

public abstract class Duck {
    protected FlyBehavior flyBehavior;
    protected QuackBehavior quackBehavior;

    public Duck() {
        flyBehavior = new FlyWithWings();   // 預設行為
        quackBehavior = new Quack();
    }

    public string Swim() => "正在游泳";
    public string PerformFly() => flyBehavior.Fly();
    public string PerformQuack() => quackBehavior.Quack();

    public void SetFlyBehavior(FlyBehavior fb) => flyBehavior = fb;
    public void SetQuackBehavior(QuackBehavior qb) => quackBehavior = qb;

    public abstract string Display();  // 子類別必須實作
}

具體鴨子類別

public class MallardDuck : Duck {
    public override string Display() => "綠頭鴨";
}

public class RedHeadDuck : Duck {
    public override string Display() => "紅頭鴨";
}

public class RubberDuck : Duck {
    public override string Display() => "橡皮鴨";
}

客戶端動態切換行為


private void PrintMsg(Duck duck) {
    txtMsg.AppendText(duck.Display());
    txtMsg.AppendText(duck.PerformFly());
    txtMsg.AppendText(duck.PerformQuack());
}

private void BtnStrategy_Click(object sender, EventArgs e) {
    txtMsg.Clear();

    // 綠頭鴨:預設飛行+嘎嘎叫
    Duck duck = new MallardDuck();
    PrintMsg(duck); txtMsg.AppendText("\r\n");

    // 紅頭鴨:飛行+吱吱叫(動態換叫聲策略)
    duck = new RedHeadDuck();
    duck.SetQuackBehavior(new Squeak());
    PrintMsg(duck); txtMsg.AppendText("\r\n");

    // 橡皮鴨:不飛+不叫+游泳(動態換雙策略)
    duck = new RubberDuck();
    duck.SetFlyBehavior(new FlyNoWay());
    duck.SetQuackBehavior(new MuteQuack());
    PrintMsg(duck);
    txtMsg.AppendText(duck.Swim());
    txtMsg.AppendText("\r\n");
}

執行結果

綠頭鴨正在用翅膀飛行嘎嘎叫
紅頭鴨正在用翅膀飛行吱吱叫
橡皮鴨不會飛不會叫正在游泳

類別關係圖解

策略模式類別圖

核心收穫

  • 行為封裝:飛行、叫聲各自獨立演化,不影響 Duck 體系
  • 執行時期切換:透過 SetFlyBehavior/SetQuackBehavior 動態改變行為,無需建立新子類別
  • 單一職責:每個策略類別只負責一種演算法,符合 SRP
  • 開放封閉:新增飛行/叫聲方式只需新增策略類,不修改既有程式碼

策略模式是「組合優於繼承」的教科書級範例,掌握它能讓你在面對多變業務規則時,從容應對而不陷入繼承地獄。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved