设计模式(三)装饰模式

装饰模式(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 }

 【总结】

装饰模式是为已有功能动态地添加更多功能的一种方式。装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

装饰模式的优点是把类中的装饰功能从类中搬移去除,这样可以简化原有的类。有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

装饰模式的装饰顺序很重要,最理想的情况是保证装饰类之间彼此独立,这样就可以以任意的顺序进行组合了。

posted @ 2015-06-17 15:53  壬子木  阅读(92)  评论(0)    收藏  举报