设计模式(三)装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

代码实现
1 abstract class Component 2 { 3 public abstract void Operation(); 4 } 5 6 class ConcreteComponent : Component 7 { 8 public override void Operation() 9 { 10 Console.WriteLine("具体对象的操作"); 11 } 12 } 13 14 abstract class Decorator : Component 15 { 16 protected Component component; 17 18 public void SetComponent(Component component) 19 { 20 this.component = component; 21 } 22 23 public override void Operation() 24 { 25 if(component != null) 26 { 27 component.Operation(); 28 } 29 } 30 } 31 32 class ConcreteDecoratorA : Decorator 33 { 34 private string addedState; // 本类的独有功能,以区别于 ConcreteDecoratorB 35 36 public override void Operation() 37 { 38 // 首先运行原 Component 的 Operation(),再执行本类的功能,如 addedState,相当于对原 Component 进行了装饰 39 base.Operation(); 40 addedState = "New State"; 41 Console.WriteLine("具体装饰对象 A 的操作"); 42 } 43 } 44 45 class ConcreteDecoratorB : Decorator 46 { 47 public override void Operation() 48 { 49 base.Operation(); 50 AddedBehavior(); 51 Console.WriteLine("具体装饰对象 B 的操作"); 52 } 53 54 private void AddedBehavior() 55 { 56 } 57 } 58 59 // 客户端代码 60 // 装饰的方法是:首先用 ConcreteComponent 实例化对象 c,然后用 ConcreteDecoratorA 的实例化对象 d1 来包装 c, 61 // 再用 ConcreteDecoratorB 的对象 d2 包装 d1,最终执行 d2 的 Operation() 62 63 Static void Main(string[] args) 64 { 65 ConcreteComponent c = new ConcreteComponent(); 66 ConcreteDecoratorA d1 = new ConcreteDecoratorA(); 67 ConcreteDecoratorB d2 = new ConcreteDecoratorB(); 68 69 d1.SetComponent(c); 70 d2.SetComponent(d1); 71 d2.Operation(); 72 73 Console.Read(); 74 }
【总结】
装饰模式是利用 SetComponent 来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
【例】没有 Component 类,直接让 服饰类 Decorator 继承 人 ConceteComponent 就可。

代码
1 class Person // ConcreteComponent 2 { 3 public Person() 4 { 5 } 6 7 private string name; 8 public Person(string name) 9 { 10 this.name = name; 11 } 12 13 public virtual void Show() 14 { 15 Console.WriteLine("装扮的{0}", name); 16 } 17 } 18 // 服饰类 19 class Finery : Person 20 { 21 protected Person component; 22 23 // 打扮 24 public void Decorate(Person component) 25 { 26 this.component = component; 27 } 28 29 public override void Show() 30 { 31 if(component != null) 32 { 33 component.Show(); 34 } 35 } 36 } 37 // 具体服饰类 38 class TShirts : Finery 39 { 40 public override void Show() 41 { 42 Console.Write("大T恤"); 43 base.Show(); 44 } 45 } 46 class BigTrouser : Finery 47 { 48 public override void Show() 49 { 50 Console.Write("垮裤"); 51 base.Show(); 52 } 53 } 54 class Sneakers : Finery 55 { 56 public override void Show() 57 { 58 Console.Write("运动鞋"); 59 base.Show(); 60 } 61 } 62 // 客户端代码 63 static void Main(string[] args) 64 { 65 Person xc = new Person("小王"); 66 67 Console.WriteLine("\n 第一种装扮"); 68 69 Sneakers pqx = new Sneakers(); 70 BigTrouser kk = new BigTrouser(); 71 TShirts dtx = new TShirts(); 72 // 装饰过程 73 pqx.Decorate(xc); 74 kk.Decorate(pqx); 75 dtx.Decorate(kk); 76 dtx.Show(); 77 }
【总结】
装饰模式是为已有功能动态地添加更多功能的一种方式。装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰模式的优点是把类中的装饰功能从类中搬移去除,这样可以简化原有的类。有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
装饰模式的装饰顺序很重要,最理想的情况是保证装饰类之间彼此独立,这样就可以以任意的顺序进行组合了。

浙公网安备 33010602011771号