後端開發 設計模式 · 第 21 / 24 篇

狀態模式:依狀態改變行為的祕訣

狀態模式 (State Pattern) 允許物件隨內部狀態改變而改變行為。本文透過 C# 手機鈴聲模式範例,示範如何消除複雜的條件判斷。

哈囉朋友們~今天我們要聊的是非常實用且有趣的狀態模式(State),這個模式讓你的物件能夠根據內部狀態的變化而自動改變行為。

🌟 狀態模式是什麼?

狀態模式允許一個物件在內部狀態改變時改變它的行為,就像換了一個角色一樣。

舉個實際例子,就像是手機的鈴聲狀態,手機在「靜音」模式時,不會響鈴;切換到「響鈴」模式後,就會有聲音通知你。這就是狀態模式的基本概念,透過改變狀態讓物件呈現不同的行為。


🤔 什麼時候適合使用狀態模式?

以下情況很適合使用狀態模式:

  • 物件的行為會根據內部狀態不同而有所改變。
  • 當有大量條件判斷,且這些條件判斷取決於物件的狀態時。
  • 希望避免使用大量的條件語句(if-else或switch),讓程式更清晰、更易於維護。

📱 C# 狀態模式範例:手機鈴聲模式

我們以手機鈴聲模式為範例來示範狀態模式。

🔕 定義狀態介面

/// <summary>
/// 狀態介面
/// </summary>
public interface IMobileState
{
    /// <summary>
    /// 依目前狀態執行提醒
    /// </summary>
    void Alert();
}

📳 建立具體狀態類別

using System;

/// <summary>
/// 響鈴模式
/// </summary>
public class RingingState : IMobileState
{
    /// <inheritdoc />
    public void Alert()
    {
        Console.WriteLine("手機正在響鈴...");
    }
}

/// <summary>
/// 靜音模式
/// </summary>
public class SilentState : IMobileState
{
    /// <inheritdoc />
    public void Alert()
    {
        Console.WriteLine("手機處於靜音模式。");
    }
}

📱 建立 Context 類別(手機)

/// <summary>
/// 手機類別,依狀態不同呈現不同行為
/// </summary>
public class MobileContext
{
    private IMobileState _state;   // 目前狀態

    public MobileContext(IMobileState initialState)
    {
        _state = initialState;
    }

    /// <summary>
    /// 切換狀態
    /// </summary>
    /// <param name="state">新的狀態</param>
    public void SetState(IMobileState state)
    {
        _state = state;
    }

    /// <summary>
    /// 執行提醒
    /// </summary>
    public void Alert()
    {
        _state.Alert();
    }
}

🚀 實際使用範例

using System;

class Program
{
    static void Main(string[] args)
    {
        MobileContext mobile = new MobileContext(new SilentState());
        mobile.Alert();

        mobile.SetState(new RingingState());
        mobile.Alert();
    }
}

🎯 執行結果

手機處於靜音模式。
手機正在響鈴...

⚠️ 狀態模式使用注意事項

  • 優點:能讓物件依據狀態不同有不同的行為,避免大量條件判斷。
  • 缺點:若狀態過多,可能導致類別數量增加,管理起來稍有複雜度。

🎉 結語

恭喜你掌握了狀態模式(State)!透過這個模式,你能讓物件行為更彈性、程式碼更清晰易維護。

持續追蹤我們的設計模式系列喔,下篇再見啦~

系列:

讀完了!你覺得這篇如何?

你的回饋會決定下一篇要寫什麼。

還有疑問

Learning path

設計模式

這篇是系列中的第 21 / 24 篇。可以順著列表補完整脈絡,也可以直接跳到需要的段落。

  1. 01 搞懂設計模式到底是什麼?
  2. 02 單例模式:只要一個就夠!
  3. 03 工廠方法模式:點披薩不用親自下廚
  4. 04 抽象工廠模式:系列產品輕鬆生產
  5. 05 原型模式:複製的藝術
  6. 06 建造者模式:一步步完成複雜任務
  7. 07 介面卡模式:讓不相容也能合作
  8. 08 橋接模式:抽象與實作分離
  9. 09 組合模式:樹狀結構的好幫手
  10. 10 裝飾者模式:讓功能自由加點
  11. 11 外觀模式:化繁為簡
  12. 12 享元模式:節省記憶體的利器
  13. 13 代理模式:控制存取的守門員
  14. 14 責任鏈模式:層層把關的處理機制
  15. 15 命令模式:靈活封裝的請求指令
  16. 16 解譯器模式:讓程式聽懂你的指令
  17. 17 迭代器模式:輕鬆遍歷集合元素
  18. 18 中介者模式:管理複雜溝通的好幫手
  19. 19 備忘錄模式:保存與恢復物件狀態
  20. 20 觀察者模式:即時通知的好幫手
  21. 21 狀態模式:依狀態改變行為的祕訣 目前閱讀
  22. 22 策略模式:靈活切換行為的好幫手
  23. 23 模板方法模式:固定流程靈活實作
  24. 24 訪問者模式:新增功能不動既有架構

Further reading

中介者模式:管理複雜溝通的好幫手 封面圖 2025-06-13 中介者模式:管理複雜溝通的好幫手 備忘錄模式:保存與恢復物件狀態 封面圖 2025-06-13 備忘錄模式:保存與恢復物件狀態 模板方法模式:固定流程靈活實作 封面圖 2025-06-13 模板方法模式:固定流程靈活實作

留言討論

用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。

閱讀導覽

約 2 分鐘

本篇所在系列 · 第 21 / 24 篇

設計模式

  1. 搞懂設計模式到底是什麼?
  2. 單例模式:只要一個就夠!
  3. 工廠方法模式:點披薩不用親自下廚
  4. 抽象工廠模式:系列產品輕鬆生產
  5. 原型模式:複製的藝術
  6. 建造者模式:一步步完成複雜任務
  7. 介面卡模式:讓不相容也能合作
  8. 橋接模式:抽象與實作分離
  9. 組合模式:樹狀結構的好幫手
  10. 裝飾者模式:讓功能自由加點
  11. 外觀模式:化繁為簡
  12. 享元模式:節省記憶體的利器
  13. 代理模式:控制存取的守門員
  14. 責任鏈模式:層層把關的處理機制
  15. 命令模式:靈活封裝的請求指令
  16. 解譯器模式:讓程式聽懂你的指令
  17. 迭代器模式:輕鬆遍歷集合元素
  18. 中介者模式:管理複雜溝通的好幫手
  19. 備忘錄模式:保存與恢復物件狀態
  20. 觀察者模式:即時通知的好幫手
  21. 狀態模式:依狀態改變行為的祕訣
  22. 策略模式:靈活切換行為的好幫手
  23. 模板方法模式:固定流程靈活實作
  24. 訪問者模式:新增功能不動既有架構
看完整系列 24 篇