设计模式——装饰模式
概念
①、什么是装饰模式
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
②、解决什么问题?
需要动态添加一些额外的职责,解决子类数据过多
③、怎么解决
通过Decorator装饰类一层一层对具体对象进行装饰
④、什么时候使用
可以动态添加或删除对象的职责,并使得需要装饰得具体组件类和具体装饰类可以独立变化,以便增加新的具体组件类和具体装饰类。
⑤、优缺点
优点
1.装饰模式与继承关系得目的都是要扩展对象得功能,但是Decorator可以提供比继承更多得灵活性
2.通过使用不同得具体装饰类以及这些装饰类得排列组合,设计师可以创造出很多不同行为得组合
缺点
3.这种比继承更加灵活机动得特性,也同时意味着更多得复杂性
4.装饰模式会导设计中出现许多小类,如果过度使用,会使程序变得很复杂
5.装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你得应用架构,以及装饰着是否合适。当然也可以改变Component接口,增加新的公开得行为,实现半透明得装饰者模式。
图
Component:是定义一个对象接口,可以给这些对象动态的添加职责。
ConcreteComponent:是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator:装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
ConcreteDecorator:具体的装饰对象,起到给Component添加职责的功能。
实例
Component类
abstract class Component { public abstract void Operation(); }
ConcreteComponent类
class ConcreteComponent:Component { public override void Operation() { Console.WriteLine("具体对象的操作"); } }
Decorator类
abstract class Decorator:Component //继承Component类 { protected Component component; public void SetComponent(Component component)//设置Component { this.component = component; } public override void Operation()//重写Operation(),实际执行的时Component的Operation() { if (component!=null ) { component.Operation(); } } }
ConcreteDecoratorA类
class ConcreteDecoratorA:Decorator //继承Decorator类 { private string addedState; //本类独有的功能 public override void Operation() { base.Operation(); //首先郧西那个原component的Operation(),在执行苯类的功能,如addedState, //相当于对原Component进行了装饰 addedState = "new State"; Console.WriteLine("具体装饰对象A的操作"); } }
ConcreteDecoratorB类
class ConcreteDecoratorB:Decorator { public override void Operation() { base.Operation(); AddedBehavior(); Console.WriteLine("具体装饰对象B的操作"); } private void AddedBehavior() { } }
客户端代码
static void Main(string[] args) { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); //装饰的方法是:首先用ConcreteComponent实例化对象c,然后 d2.SetComponent(d1); //用ConcreteDecoratorA的实例化对象d1来包装c,再用 d2.Operation(); //ConcrteDecoratorB的对象d2包装d1,最终执行d2的Operation() Console.Read(); }