定义
装饰模式:动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。
举例
如:人穿上T恤、鞋子、裤子等,进行自由搭配(如:西装、领带、皮鞋;T恤、垮裤、球鞋这样的组合)
装饰模式是一种对象结构型模式,它以对客户透明的方式动态地给一个对象附加上更多的责任,可以在不需要创建更多子类的情况下,让对象的功能得以扩展。
结构
实现
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;
}
//重写Operation(),实际执行的是Component的Operation()
public override void Operation()
{
if(component != null)
{
component.Operation();
}
}
}
class ConcreteDecoratorA: Decorator
{
private string addedState; //用于区别ConcreteDecoratorB
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();
//首先调用对象c,然后用ConcreteDecoratorA实例化d1来包装c
//再用ConcreteDecoratorB对象d2包装d1,最终执行d2的Operation()
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
优点
- (1)对于扩展一个对象的功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加。
- (2)装饰模式可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。
- (3)装饰模式可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更为强大的对象。
- (4)在装饰模式中,具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,且原有类库代码无须改变,符合开闭原则。
缺点
- (1)使用装饰模式进行系统设计时将产生很多小对象,导致会占用更多的系统资源,在一定程度上影响程序的性能。
- (2)易于出错、排错困难
适用环境
- (1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- (2)当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。