6.6 装扮模式总结
装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装扮模式是为已有功能动态地添加更多功能的一种方式。
装饰模式的优点:
有效地把类的核心职责和装饰功能区分开了(将装饰功能从类中移除,简化了原有的类)。而且可以去除相关类中重复的装饰逻辑(具体的装饰类都继承了抽象装饰类)。
需要注意的问题:
装饰模式的顺序很重要,比如加密数据和过滤词汇都可以是数据持久化(存储)以前的装饰功能,但若先加密了数据再用过滤功能就会出问题了,最理想的情况,是保证装饰类之间彼此独立,这样它们就可以以任意的顺序进行组合了。
6.4 装饰模式
装饰模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
基本的实现代码:
Component 类:
abstract class Component { public abstract void Operation(); }
Component 定义了一个对象接口(抽象类的抽象方法),可以给这些对象动态地添加职责。
ConcreteComponent 类:
class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("具体对象的操作"); } }
ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator 类:(抽象的装饰类,需要继承定义的对象接口)
abstract class Decorator : 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(); } } }
Decorator,抽象装饰类,继承了 Component,从类外面来扩展 Component 类的功能,但对于 Component 来说,是无需知道 Decorator 的存在的。
具体的装饰类:
class ConcreteDecoratorA : Decorator { private string addedState; //本类的独有功能,以区别于ConcreteDecoratorB public override void Operation() { base.Operation(); //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰 addedState = "New State"; Console.WriteLine("具体装饰对象A的操作"); } } class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); //首先运行原Component的Operation(),再执行本类的功能,AddBehavitor(),相当于对原Component进行了装饰 AddBehavitor(); Console.WriteLine("具体装饰对象A的操作"); } private void AddBehavitor() //本类独有的方法,以区别于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(); //装饰的方法是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation() Console.Read(); }
6.5 装饰模式的实际应用
“Person” 类(ConcreteComponent)
class Person { public Person() { } private string name; public Person(string name) { this.name = name; } public virtual void Show() { Console.WriteLine("装扮的{0}", name); } }
服饰类(Decorator)
class Finery : Person { protected Person component; //打扮 public void Decorate(Person component) { this.component = component; } public override void Show() { if(component != null) { component.Show(); } } }
具体服饰类(ConcreteDecorator)
class TShirts : Finery { public override void Show() { Console.WriteLine("大T恤 "); base.Show(); } } class BigTrouser : Finery { public override void Show() { Console.WriteLine("垮裤 "); base.Show(); } }
客户端代码
static void Main(string[] args) { Person xc = new Person("小菜"); Console.WriteLine("\n第一种装扮:"); BigTrouser kk = new BigTrouser(); //垮裤 TShirts dtx = new TShirts(); //大T恤 kk.Decorate(xc); //装扮过程 dtx.Decorate(kk); dtx.Show(); Console.Read(); }