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

裝飾者模式:讓功能自由加點

裝飾者模式 (Decorator Pattern) 讓你不需修改原有程式碼,就能動態為物件添加新功能。本文透過 C# 咖啡加料範例輕鬆學會。

哈囉朋友們~今天要介紹的設計模式可是非常實用又有趣的喔,那就是 裝飾者模式(Decorator)!

🌟 什麼是裝飾者模式?

裝飾者模式讓你在不修改現有物件程式碼的情況下,動態地增加新的功能。簡單來說,就是「包一層再包一層」的概念。

想像一下買一杯飲料,你可以加珍珠、椰果、鮮奶油等等,每個配料就像一個裝飾,你可以自由組合,做出你專屬的飲料,這就是裝飾者模式的概念!


🤔 什麼情況適合用裝飾者模式?

當你遇到以下情境時,很適合使用裝飾者模式:

  • 需要動態地為物件增加或移除功能。
  • 不想直接修改原本類別的程式碼,避免影響原本物件的穩定性。
  • 想要彈性地組合不同的功能,並且可以隨時調整功能。

🎂 C# 裝飾者模式範例

我們用最容易理解的「咖啡加料」案例,來看看怎麼實作裝飾者模式吧!

☕ 定義抽象元件(Component)

using System;

/// <summary>
/// 咖啡抽象元件
/// </summary>
public abstract class Coffee
{
    /// <summary>
    /// 取得描述
    /// </summary>
    public abstract string GetDescription();

    /// <summary>
    /// 供應咖啡
    /// </summary>
    public abstract void Serve();
}

☕ 實作具體元件

using System;

/// <summary>
/// 基本咖啡
/// </summary>
public class SimpleCoffee : Coffee
{
    /// <summary>
    /// 取得描述
    /// </summary>
    public override string GetDescription() => "基本咖啡";

    /// <summary>
    /// 供應咖啡
    /// </summary>
    public override void Serve()
    {
        Console.WriteLine("提供一杯基本咖啡。");
    }
}

🍯 建立裝飾者(Decorator)

using System;

/// <summary>
/// 裝飾者抽象類別
/// </summary>
public abstract class CoffeeDecorator : Coffee
{
    /// <summary>
    /// 被裝飾的咖啡
    /// </summary>
    protected Coffee _coffee;

    protected CoffeeDecorator(Coffee coffee)
    {
        _coffee = coffee;
    }

    /// <summary>
    /// 取得描述
    /// </summary>
    public override string GetDescription() => _coffee.GetDescription();

    /// <summary>
    /// 供應咖啡並套用裝飾
    /// </summary>
    public override void Serve()
    {
        _coffee.Serve();
    }
}

🥛 實作具體裝飾者(牛奶、糖漿)

using System;

/// <summary>
/// 牛奶裝飾者
/// </summary>
public class MilkDecorator : CoffeeDecorator
{
    public MilkDecorator(Coffee coffee) : base(coffee) {}

    public override void Serve()
    {
        base.Serve();
        Console.WriteLine("加上牛奶。");
    }

    public override string GetDescription() => base.GetDescription() + " + 牛奶";
}

/// <summary>
/// 糖漿裝飾者
/// </summary>
public class SyrupDecorator : CoffeeDecorator
{
    public SyrupDecorator(Coffee coffee) : base(coffee) {}

    public override void Serve()
    {
        base.Serve();
        Console.WriteLine("加上糖漿。");
    }

    public override string GetDescription() => base.GetDescription() + " + 糖漿";
}

🚀 實際使用範例

using System;

class Program
{
    static void Main(string[] args)
    {
        Coffee coffee = new SimpleCoffee();

        // 加牛奶
        Coffee milkCoffee = new MilkDecorator(coffee);

        // 再加糖漿
        Coffee syrupMilkCoffee = new SyrupDecorator(milkCoffee);

        syrupMilkCoffee.Serve();
    }
}

🎯 執行結果

提供一杯基本咖啡。
加上牛奶。
加上糖漿。

⚠️ 使用裝飾者模式注意事項

  • 優點:靈活性極高,可以自由搭配增加功能,不會修改現有程式碼。
  • 缺點:可能產生大量的小型類別,增加系統複雜性。

🎉 結語

恭喜你又輕鬆學會了一個重要又實用的設計模式—裝飾者模式(Decorator)!有了這個技巧,未來你就可以輕鬆地動態增加各種你想要的功能啦。

繼續追蹤我們的設計模式系列吧,下篇再見囉~

系列:

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

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

還有疑問

Learning path

設計模式

這篇是系列中的第 10 / 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 分鐘

本篇所在系列 · 第 10 / 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 篇