C#設計模式19——裝飾器模式的寫法

2023-06-05 18:01:07

裝飾器模式(Decorator Pattern)是一種結構型設計模式,它允許你動態地給一個物件新增一些額外的職責,而不需要修改這個物件的程式碼。

What(什麼)

裝飾器模式是一種結構型設計模式,它允許你動態地給一個物件新增一些額外的職責,而不需要修改這個物件的程式碼。

在裝飾器模式中,你可以定義一個裝飾器類,它包含一個指向被裝飾物件的參照,並且實現了與被裝飾物件相同的介面。裝飾器類可以在執行時動態地給被裝飾物件新增一些額外的行為,而不會影響到原有的行為。

Why(為什麼)

在軟體開發過程中,經常會遇到需要給一個物件新增一些額外的行為的情況。如果直接修改這個物件的程式碼,可能會引起其他程式碼的不穩定性,而且會導致程式碼的可維護性變差。此時,裝飾器模式就可以很好地解決這個問題。

使用裝飾器模式,你可以在執行時動態地給一個物件新增一些額外的職責,而不需要修改這個物件的程式碼。這樣,你就可以保持原有程式碼的穩定性和可維護性,同時還能夠滿足新的需求。

How(怎麼做)

裝飾器模式的實現需要以下幾個步驟:

1. 定義一個介面,它包含了被裝飾物件和裝飾器物件需要實現的方法。
2. 實現一個具體的類,它實現了這個介面,並且包含了一些基本的行為。
3. 實現一個裝飾器類,它也實現了這個介面,並且包含了一個指向被裝飾物件的參照。
4. 在裝飾器類中,實現需要新增的額外行為,並且在呼叫被裝飾物件的方法時,也呼叫相應的方法。
5. 在使用者端程式碼中,建立一個具體的物件,並且用裝飾器類動態地給它新增一些額外的行為。

 Where(在哪裡使用)

裝飾器模式適用於以下情況:

- 當你需要在不修改物件程式碼的情況下,給一個物件新增一些額外的行為時,可以使用裝飾器模式。
- 當你需要動態地給一個物件新增一些額外的行為時,可以使用裝飾器模式。
- 當你需要給一個物件新增一些行為,但是這些行為可能會被頻繁地修改或者刪除時,可以使用裝飾器模式。

Who(誰使用)

裝飾器模式適用於以下角色:

- Component:定義了被裝飾物件和裝飾器物件需要實現的方法。
- ConcreteComponent:實現了 Component 介面,並且包含了一些基本的行為。
- Decorator:實現了 Component 介面,並且包含了一個指向被裝飾物件的參照。
- ConcreteDecorator:實現了 Decorator 介面,並且在呼叫被裝飾物件的方法時,新增了額外的行為。

Example(範例)

以下是一個使用裝飾器模式的範例:

// Component 介面
public interface IShape
{
    void Draw();
}

// ConcreteComponent 類
public class Rectangle : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a rectangle.");
    }
}

// Decorator 類
public abstract class ShapeDecorator : IShape
{
    protected IShape decoratedShape;

    public ShapeDecorator(IShape decoratedShape)
    {
        this.decoratedShape = decoratedShape;
    }

    public virtual void Draw()
    {
        decoratedShape.Draw();
    }
}

// ConcreteDecorator 類
public class RedShapeDecorator : ShapeDecorator
{
    public RedShapeDecorator(IShape decoratedShape) : base(decoratedShape)
    {
    }

    public override void Draw()
    {
        decoratedShape.Draw();
        Console.WriteLine("Border Color: Red");
    }
}

// 使用者端程式碼
public class Client
{
    static void Main(string[] args)
    {
        // 建立一個具體的物件
        IShape rectangle = new Rectangle();

        // 用裝飾器類動態地給它新增一些額外的行為
        IShape redRectangle = new RedShapeDecorator(rectangle);

        // 呼叫方法,輸出結果
        rectangle.Draw(); // 輸出 "Drawing a rectangle."
        redRectangle.Draw(); // 輸出 "Drawing a rectangle." 和 "Border Color: Red"
    }
}

在上面的範例程式碼中,我們定義了一個 `IShape` 介面,它包含了一個 `Draw` 方法,用於繪製圖形。然後,我們實現了一個 `Rectangle` 類,它實現了 `IShape` 介面,並且包含了一個基本的行為。接著,我們定義了一個 `ShapeDecorator` 抽象類,它實現了 `IShape` 介面,並且包含了一個指向被裝飾物件的參照。最後,我們實現了一個 `RedShapeDecorator` 類,它繼承了 `ShapeDecorator` 類,並且在呼叫被裝飾物件的 `Draw` 方法時,新增了一個額外的行為。

在使用者端程式碼中,我們建立了一個具體的物件 `rectangle`,然後用 `RedShapeDecorator` 類動態地給它新增了一個額外的行為。最後,我們呼叫了 `Draw` 方法,輸出了結果。在本例中,輸出了 "Drawing a rectangle." 和 "Border Color: Red"。