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; //本类的独有功能,以区别于ConcreteDecoratorBpublic 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();}