设计模式之装饰模式
一、定义:装饰模式就是动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
二、思想:组合优于继承,通过对象之间的组合关系,替代了通过生成子类来扩展功能的传统方式,从而提供了更灵活、更强大的扩展能力。
三、结构图:

- 抽象组件: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(); }
四、优缺点:
优点:
-
比继承更灵活:这是它最大的优点。可以在运行时动态地给对象添加或撤销功能。
-
避免“类爆炸”:避免了为每一种功能组合都创建一个子类,大大减少了系统中类的数量。
-
符合开闭原则:无需修改现有类(对修改关闭),通过添加新的装饰类即可扩展功能(对扩展开放)。
-
职责清晰:每个装饰类只负责一个特定的功能,符合单一职责原则。
缺点:
-
增加系统复杂度:会产生大量的小类,增加了学习和维护的难度。
-
调试困难:由于功能由多层装饰叠加而成,排查问题时跟踪调用栈会比较麻烦。
浙公网安备 33010602011771号