模式开发之旅(12):装饰模式
2010-07-24 15:18:34装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
Component是定义一个对象接口,可以给这些对象动态地添加职责。ComcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外部来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ComponentDecorator就是具体的装饰对象,起到给Component添加职责的功能。
装饰模式是结构型模式的巅峰设计,之所以这么说,是因为它不仅使用了继承,而且还使用了组合。这是一种比较烧脑的设计模式。我们来看一下装饰模式的代码实现:
abstract class Component
{
public abstract void Operation();
}
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
abstract class Decorator : Component //继承Component
{
protected Component component; //组合Component
public void SetComponent(Component component) //设置Component
{
this.component = component;
}
public override void Operation() //重写Operation(),实际执行的是Component的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() //本类独有的方法,以区别ConcreteDecoratorA
{
}
}
//客户端代码
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();
}
装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外,装饰器模式还有一个特点,那就是可以对原始类嵌套使用多个装饰器。为了满足这个应用场景,在设计的时候,装饰器类需要跟原始类继承相同的抽象类或者接口。
装饰模式是为已有功能动态地添加更多功能的一种方式。但到底什么时候用它呢?我们在起初设计中,当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要功能,但这种做法的问题在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定环境下才会执行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。