设计模式之装饰模式

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

二、思想:组合优于继承,通过对象之间的组合关系,替代了通过生成子类来扩展功能的传统方式,从而提供了更灵活、更强大的扩展能力。

三、结构图:

image

  • 抽象组件:Component是一个接口或抽象类,定义了被装饰对象和装饰器共有的、需要被扩展的核心方法 
abstract class Component
{
    public abstract void Operation ();
}
  • 具体组件:ConcreteComponent实现了Component接口的原始对象,它是被装饰的目标,也是功能扩展的起点。  
class ConcreteComponent : Component
{
    public override void Operation ()
    {
        Console.WriteLine("具体对象的操作");
    }    
}
  • 抽象装饰:Decorator同样实现了Component接口,并持有一个指向Component对象的引用。它负责将客户端的请求转发给被包装的Component对象
abstract class Decorator : Component
{
    protected Component component;
    //设置Component
    public void SetComponent (Component componentt)
    {
        this.component=component;
    }
    
    //重写Operation,实际执行的是Component的Operation
    public override void Operation()
    {
        if (component != null)
        {
            component.Operation();
        }
    }
}
  • 具体装饰:ConcreteDecorator继承自Decorator,在调用父类方法(即转发请求)的前后,添加自己特定的新行为或功能
class ConcreteDecoratorA : Decorator
{
    private string addedState;//本类的独有功能,以区别于ConcreteDecoratorB
    public override void Operation()    
    {
        //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
        base.Operation();
        addedState = "New State";
        Console.WriteLine("具体装饰对象A的操作");
    }    
}

class ConcreteDecoratorB : Decoratoor
{
    public override void Operation()
    {
        //首先运行原Component的Operation(),再执行本类的功能,如AddedBehavior(),相当于对原Component进行了装饰
        base.Operation();
        AddedBehavior();
        Console.WriteLine("具体装饰对象B的操作");
    }
    //本类独有的方法,以区别于ConcreteDecoratorB
    private void AddedBehavior()
    {        
    }
}

客户端代码:

static void Main(string[] args)
{
    ConcreteComponent c= new ConcreteComponent();
    ConcreteDecoratorA dl = new ConcreteDecorratorA();
    ConcreteDecoratorB d2 = new ConcreteDecoratorB();
    
    //装饰的方法是:首先用ConcreteComponent实例化对象c,
    //然后用ConcreteDecoratorA的实例化对象dl来包装c,
    //再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()
    dl.SetComponent(c);
    d2.SetComponent(d1);
    d2.Operation();
    
    Console.Read();
}

四、优缺点:

优点

  • 比继承更灵活:这是它最大的优点。可以在运行时动态地给对象添加或撤销功能

  • 避免“类爆炸”:避免了为每一种功能组合都创建一个子类,大大减少了系统中类的数量

  • 符合开闭原则:无需修改现有类(对修改关闭),通过添加新的装饰类即可扩展功能(对扩展开放)

  • 职责清晰:每个装饰类只负责一个特定的功能,符合单一职责原则

缺点

  • 增加系统复杂度:会产生大量的小类,增加了学习和维护的难度

  • 调试困难:由于功能由多层装饰叠加而成,排查问题时跟踪调用栈会比较麻烦

posted @ 2026-07-03 10:44  LXLR  阅读(5)  评论(0)    收藏  举报