定义:动态地给一个对象增加其他职责,就增加对象的功能来说,装饰模式比生成子类实现更为灵活。
UML图如下:
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象和抽象装饰器。
- 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
- 抽象装饰(Decorator)角色:持有一个构件(Component)对象的实例,以用来对它进行装饰,并定义一个与抽象构件接口一致的接口。
- 具体装饰(Concrete Decorator)角色:负责给构件对象"加上"附加的功能。
- 结构图代码:
- //抽象构件,定义了具体构件和抽象装饰要实现的方法
- interface Component
- {
- void Operation();
- }
- //定义具体构件
- class ConcreteComponent : Component
- {
- public void Operation()
- {
- Console.WriteLine("ConcreteComponent Operation");
- }
- }
- //定义抽象装饰者。抽象装饰者也实现了抽象构件的接口
- abstract class Decorator : Component
- {
- //把一个抽象构件作为抽象装饰的成员变量。
- protected Component comp;
- //在抽象装饰者的构造函数中为抽象构件初始化。
- public Decorator(Component c)
- {
- this.comp = c;
- }
- //还未实现的接口的方法。
- public abstract void Operation();
- }
- //具体装饰者A,继承自抽象装饰。
- class ConcreteDecoratorA : Decorator
- {
- private string addedState; //具体装饰者中新增的成员变量
- public ConcreteDecoratorA(Component c) : base(c) { }
- public string AddedState //具体装饰者中新增的属性
- {
- set
- {
- addedState = value;
- }
- }
- //具体装饰者实现了接口中定义的方法
- public override void Operation()
- {
- comp.Operation(); //可以调用原构件对象的Operation方法。
- Console.WriteLine("ConcreteDecoratorA Operation {0}",addedState);
- }
- }
- //具体装饰者B,继承自抽象装饰。
- class ConcreteDecoratorB : Decorator
- {
- public ConcreteDecoratorB(Component c) : base(c) { }
- public override void Operation()
- {
- comp.Operation(); //可以调用原构件对象的Operation方法。
- Console.WriteLine("ConcreteDecoratorB Operation ");
- }
- // 具体装饰者实现了接口中定义的方法
- public void AddedBehavior()
- {
- Console.WriteLine("This is Added Behavior");
- }
- }
- class Client
- {
- public static void Main()
- {
- //原生的具体构件
- ConcreteComponent cc = new ConcreteComponent();
- cc.Operation();
- //把原生的具体构件用具体装饰者A进行一次包装
- ConcreteDecoratorA cda = new ConcreteDecoratorA(cc);
- cda.AddedState = "Decorator OK ";
- cda.Operation();
- //把原生的具体构件用具体装饰者B进行一次包装
- ConcreteDecoratorB cdb = new ConcreteDecoratorB(cc);
- cdb.AddedBehavior();
- cdb.Operation();
- //把被A包装完的具体构件再用用具体装饰者B进行二次包装
- ConcreteDecoratorB cdbcda = new ConcreteDecoratorB(cda);
- cdbcda.Operation();
- }
- }
- Decorator与Component之间既是Is a...的继承关系,又是Has a...的组合关系。使用具体装饰类(ConcreteDecorator)来装饰具体构件对象(ConcreteComponent),装饰完的对象依旧是个Component类型。
Decorator模式解决的是类的功能的多向扩展,而不是单纯的类的继承。
Decorator模式提供了比继承更灵活的功能扩展,通过使用不同具体装饰对构件对象的排列组合地包装,能够不同功能的组合。