定义:
动态的给一个对象添加一些额外的职责,就增加新功能来说,它比继承更为灵活
机构图:
设计原则:
1. 多用组合,少用继承。
利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。
2. 类应该对扩展开放,对修改关闭。
关键点:
1. 装饰者和被装饰有相同的超类型。
2. 可以用一个或多个装饰者包装一个对象。
3. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。
4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。
5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。
实例:
//被装饰者的接口
abstract class Component
{
public abstract void Operation();
}
//具体的被装饰者
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
//装饰者的接口,继承了被装饰者,只是类型上的继承,不是行为上
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
//具体的装饰者,继承了装饰者,包装了一个装饰者对象,并且拥有自己的特点
class ConcreteDecoratorA : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();//所包装的装饰对象
addedState = "New State";
Console.WriteLine("具体装饰对象A的操作");
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
}
private void AddedBehavior()
{
}
}
//客户端调用
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
Console.Read();
}
}
装饰者模式缺点:会产生比使用继承关系更多的对象。