2013年5月14日 星期二

設計模式:裝飾模式 (Decorator Pattern)

裝飾模式 (Decorator Pattern),以下程式碼以 C# 為例

說明:
在某一物件動態加上功能。
一層一層的將功能套上去,每一層執行的是不同的物件。

範例:
有一遊戲,有以下三個功能。

功能A:把玩家給我,我就能將玩家裝備寶劍
功能B:把玩家給我,我就能將玩家裝備護盾
功能C:把玩家給我,我就能將玩家裝備靴子

希望達成如下的效果
static void Main(string[] args)
{
    // 玩家
    Player player = new Player();

    // 裝飾功能A (寶劍裝備)
    Decorator_A A = new Decorator_A();
    A.SetPlayer(player); // 將"玩家"給功能A,增加寶劍裝備

    // 裝飾功能B (護盾裝備)
    Decorator_B B = new Decorator_B();
    B.SetPlayer(A); // 繼續給功能B,增加護盾裝備

    // 裝飾功能C (靴子裝備)
    Decorator_C C = new Decorator_C();
    C.SetPlayer(B); // 繼續給功能C,增加靴子裝備

    // 開始一層一層執行裝備東西
    C.Operation();

    Console.ReadLine();
}
執行結果:
玩家的裝備:
裝備了 寶劍,攻擊力+10
裝備了 護盾,防禦力+5
裝備了 靴子,速度+2


實現重點在於,
功能A、功能B、功能C 除了能接受玩家 player為處理對象,也能接受彼此為處理對象,才可以一層一層將功能疊加上去。
也就是「被裝飾者」和「裝飾功能」要繼承某一共同類別,並實做某一共同的方法,
我們將此共同類別抽出來當一個抽象類別,叫做 Component。


其餘程式碼
// 「元件」抽像類別,定義了「被裝飾者」和「裝飾功能」要實做的方法
abstract class Component
{
    public abstract void Operation();
}

// 玩家(被裝飾者),實做元件抽像介面
class Player : Component
{
    public override void Operation()
    {
        Console.WriteLine("玩家的裝備:");
    }
}

// 裝飾功能抽像類別,繼承「元件」抽像類別
abstract class Decorator : Component
{
    protected Component component;

    // 設定玩家(也可理解成設定Component)
    public void SetPlayer(Component component)
    {
        this.component = component;
    }

    public override void Operation()
    {
        if (this.component != null)
        {
            this.component.Operation();
        }
    }
}

// 裝飾功能A (寶劍裝備)
class Decorator_A : Decorator
{
    public override void Operation()
    {
        base.Operation(); // 執行原本玩家的功能
        Console.WriteLine("裝備了 寶劍,攻擊力+10"); // 執行新功能
    }
}

// 裝飾功能B (護盾裝備)
class Decorator_B : Decorator
{
    public override void Operation()
    {
        base.Operation(); // 執行原本玩家的功能
        Console.WriteLine("裝備了 護盾,防禦力+5"); // 執行新功能
    }
}

// 裝飾功能C (靴子裝備)
class Decorator_C : Decorator
{
    public override void Operation()
    {
        base.Operation(); // 執行原本玩家的功能
        Console.WriteLine("裝備了 靴子,速度+2"); // 執行新功能
    }
}

相關連結:設計模式整理列表

沒有留言:

張貼留言