装饰模式

摘自《大话设计模式》(程杰 著)

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

image

Component 是定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。

装饰模式是利用 SetComponent 来对对象进行包装的。
这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

基本代码实现

Component.cs

abstract class Component
{
    public abstract void Opearation();
}

ConcreteComponent.cs

class ConcreteComponent: Component
{
    public override void Operation()
    {
        Console.WriteLine("具体的操作");
    }
}

Decorator.cs

abstract class Decorator: Component
{
    protected Component component;

    // 设置 Component
    public void SetComponent(Component component)
    {
        this.component = component;
    }

    // 重写 Operation(), 实际执行的是 Component 的 Operation()
    public override void Operation()
    {
        if (component != null)
        {
            component.Operation();
        }
    }
}

ConcreteDecorator.cs

class ConcreteDecoratorA: Decorator
{
    // 本类独有功能,用以区别 ConcreteDecoratorB
    private string addedState;

    public override void Operation()
    {
        // 首先执行原 Component 的 Operation()
        base.Operation();
        // 再执行本类功能
        addedState = "New State";
        Console.WriteLine("具体装饰对象A的操作");
    }
}

class ConcreteDecoratorB : Decorator
{
    public override void Operation()
    {
        // 首先执行原 Component 的 Operation()
        base.Operation();
        // 再执行本类功能
        AddedBehavior();
        Console.WriteLine("具体装饰对象B的操作");
    }

    // 本类独有方法,用来区别 ConcreteDecoratorA
    private void AddedBehavior()
    {

    }
}

Program.cs

static void Main(string[] arg)
{
    ConcreteComponent c = new ConcreteComponent();
    ConcreteDecoratorA d1 = new ConcreteDecoratorA();
    ConcreteDecoratorB d2 = new ConcreteDecoratorB();

    d1.SetComponent(c);
    d2.SetComponent(d1);
    d2.Operation();

    Console.Read();
}

实例:服饰装扮

如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

image

Person.cs (ConcreteComponent)

class Person
{
    public Person()
    {

    }

    private string name;
    public Person(string name)
    {
        this.name = name;
    }

    public virtual void Show()
    {
        Console.WriteLine("装扮的{0}",name);
    }
}

Finery.cs (Decorator)服饰类

class Finery : Person
{
    protected Person component;

    // 打扮
    public void Decorate(Person component)
    {
        this.component = component;
    }

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

具体服饰类 ConcreteDecorator

class TShirts: Finery
{
    public override void Show()
    {
        Console.Write("大T恤");
        base.Show();
    }
}

class BigTrouser : Finery
{
    public override void Show()
    {
        Console.Write("垮裤");
        base.Show();
    }
}

// 其余类似

客户端代码

Person person = new Person("Harry");

Console.WriteLine("\n第一种装扮:");

TShirts tshirt = new TShirts();
BigTrouser bigtrouser = new BigTrouser();

tshirt.Decorate(person);
bigtrouser.Decorate(tshirt);
bigtrouser.Show();
posted @ 2025-12-11 09:19  苦涩如影相随固  阅读(26)  评论(0)    收藏  举报