设计模式---装饰模式

来源:互联网 发布:清朝灭亡 知乎 编辑:程序博客网 时间:2024/05/16 23:36

http://blog.csdn.net/u010955843/article/details/24875903   


 相同点:建造者模式是所有的部件在内部组装完毕之后,然后显示出来,装饰模式似乎与其有着共同之处,那就是你不能在人前一件一件地穿衣服,你肯定会在某个别人看不见的地方把衣服穿好,才出来见人的。

    不同点:建造者模式要求建造的过程必须是稳定的。而装饰模式的建造过程不是稳定的,衣服你可以先穿裤子,再穿褂子,或者干脆不穿褂子,穿个短袖等等,是内部的建造过程不是稳定的。

装饰模式是对于一个东西做的是表面外部的装扮,而建造者模式是对一个东西整体框架的一个组装。

    那么具体什么是装饰模式?什么又是建造者模式呢?

  Ø  装饰模式

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

    程序代码

[csharp] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace ConsoleApplication7  
  7. {  
  8.     class Person  
  9.     {  
  10.         public Person()  
  11.         { }  
  12.         private string name;  
  13.         public Person(string name)  
  14.         {  
  15.             this.name = name;  
  16.   
  17.         }  
  18.         public virtual void Show()  
  19.         {  
  20.             Console.WriteLine("装扮{0}",name );  
  21.         }  
  22.     }  
  23.   
  24.     class Finery : Person  
  25.     {  
  26.         protected Person component;  
  27.         //打扮  
  28.         public void Decorate(Person component)  
  29.         {  
  30.             this.component = component;  
  31.         }  
  32.         public override void Show()  
  33.         {  
  34.             if (component != null)  
  35.             {  
  36.                 component.Show();  
  37.             }  
  38.   
  39.         }  
  40.     }  
  41.     class TShirts : Finery  
  42.     {  
  43.         public override void Show()  
  44.         {  
  45.             Console.Write("大体恤");  
  46.                 base.Show ();  
  47.         }  
  48.     }  
  49.     class BigTrouser : Finery  
  50.     {  
  51.         public override void Show()  
  52.         {  
  53.             Console.Write("垮裤");  
  54.             base.Show();  
  55.         }  
  56.     }  
  57.     class Sneakers : Finery  
  58.     {  
  59.         public override void Show()  
  60.         {  
  61.             Console.Write("破球鞋");  
  62.             base.Show();  
  63.         }  
  64.     }  
  65.     class LeatherShoes : Finery  
  66.     {  
  67.         public override void Show()  
  68.         {  
  69.             Console.Write("皮鞋");  
  70.             base.Show();  
  71.         }  
  72.     }  
  73.     class Suit : Finery  
  74.     {  
  75.         public override void Show()  
  76.         {  
  77.             Console.Write("西装");  
  78.             base.Show();  
  79.         }  
  80.     }  
  81.     class Tie : Finery  
  82.     {  
  83.         public override void Show()  
  84.         {  
  85.             Console.Write("领带");  
  86.             base.Show();  
  87.         }  
  88.     }  
  89. }  
  90. </strong></span>  
    客户端代码

[csharp] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace ConsoleApplication7  
  7. {  
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             Person xc = new Person("小菜");  
  13.             Console.WriteLine ("\n第一种装扮:");  
  14.             Sneakers pqx=new Sneakers ();  
  15.             BigTrouser kk=new BigTrouser ();  
  16.             TShirts dtx=new TShirts ();  
  17.   
  18.             pqx .Decorate (xc);  
  19.             kk.Decorate (pqx);  
  20.             dtx.Decorate (kk);  
  21.             dtx.Show ();  
  22.               
  23.             Console.WriteLine ("\n第二种装扮:");  
  24.             LeatherShoes px=new LeatherShoes ();  
  25.             Tie ld=new Tie ();  
  26.             Suit xz=new Suit ();  
  27.   
  28.             px.Decorate (xc);  
  29.             ld.Decorate (px);  
  30.             xz.Decorate (ld);  
  31.             xz.Show ();  
  32.   
  33.             Console.Read();  
  34.   
  35.         }  
  36.     }  
  37. }  
  38. </strong></span>  

  Ø  建造者模式

    建造者模式(Builder):将一个复杂对象的构建和它的表示相分离,使得同样的构建过程可以创建不同的表示。

    程序代码

[csharp] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Drawing;  
  6.   
  7. namespace ConsoleApplication8  
  8. {  
  9.     //class Graphics  
  10.     //{  
  11.     //    IList <string >parts=new List <string >;  
  12.     //    public void Add(string part)  
  13.     //    {  
  14.     //        parts.Add (part );  
  15.     //    }  
  16.     //    public void Show()  
  17.     //    {  
  18.     //        Console.WriteLine ("\n图 创建头、身体、左手、右手、左腿、右腿");  
  19.     //        foreach (string part in parts)  
  20.     //        {  
  21.     //            Console.WriteLine (part);  
  22.     //        }  
  23.     //    }  
  24.     //}  
  25.      abstract class PersonBuilder  
  26.         {  
  27.          protected Graphics g;  
  28.          protected Pen p;  
  29.           
  30.          public PersonBuilder(Graphics g, Pen p)  
  31.             {  
  32.              this.g = g;  
  33.              this.p = p;  
  34.             }  
  35.             public abstract void Buildhead();  
  36.             public abstract void BuildBody();  
  37.             public abstract void BuildArmLeft();  
  38.             public abstract void BuildArmRight();  
  39.             public abstract void BuildLegLeft();  
  40.             public abstract void BuildLegRight();  
  41.   
  42.     }  
  43.      class PersonThinBuilder : PersonBuilder  
  44.      {  
  45.          public PersonThinBuilder(Graphics g, Pen p)  
  46.              : base(g, p)  
  47.          { }  
  48.          public override void Buildhead()  
  49.          {  
  50.              g.DrawEllipse(p,50,20,30,30);  
  51.          }  
  52.          public override void BuildBody()  
  53.          {  
  54.             g.DrawRectangle(p,60,50,10,50);  
  55.   
  56.          }  
  57.          public override void BuildArmLeft()  
  58.          {  
  59.              g.DrawLine(p,60,50,40,100);  
  60.   
  61.          }  
  62.          public override void BuildArmRight()  
  63.          {  
  64.             g.DrawLine(p,70,50,90,100);  
  65.          }  
  66.          public override void BuildLegLeft()  
  67.          {  
  68.             g.DrawLine(p,60,100,45,150);  
  69.          }  
  70.          public override void BuildLegRight()  
  71.          {  
  72.              g.DrawLine(p,70,100,85,150);  
  73.          }  
  74.      }  
  75.      class PersonDirector  
  76.      {  
  77.          private PersonBuilder pb;  
  78.          public PersonDirector(PersonBuilder pb)  
  79.          {  
  80.              this.pb = pb;  
  81.          }  
  82.          public void CreatePerson()  
  83.          {  
  84.              pb.Buildhead();  
  85.              pb.BuildBody();  
  86.              pb.BuildArmLeft();  
  87.              pb.BuildArmRight();  
  88.              pb.BuildLegLeft();  
  89.              pb.BuildLegRight();  
  90.          }  
  91.      }  
  92.   
  93. }  
  94. </strong></span>  

客户端代码

[csharp] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;"><strong> <span style="white-space:pre">  </span>    Pen p = new Pen(Color.Yellow);  
  2.             PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(),p);  
  3.             PersonDirector pbThin = new PersonDirector(ptb);  
  4.   
  5.             pbThin .CreatePerson();</strong></span>  

  Ø  两者的比较

    u  装饰模式

    由上例我们可以看出,装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要修饰的对象,因此,当需要执行特殊行为的时候,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

    优点:把类中的装饰功能从类中搬移去除,这样简化了原来的类。

           有效地把类的核心职责与装饰功能区分开了。并且可以去除相关类中重复的装饰逻辑。

    缺点:1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

          2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

          3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应    该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,    实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

          4、此外装饰模式的顺序很重要,如加密数据和过滤词汇如果先加密再过滤。肯定是会出问题的。

    u  建造者模式

    由上例可以看出,建造者主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但是对象内部的构件通常是面临着复杂的变化。

    优点就是:使得建造代码与表示代码分离。由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

    这不免要想起工厂模式以及抽象工厂模式等等,它们的共同点就是使用者不必知道内部组成的细节,但是又有所不一样,那就是建造者模式最主要的功能是基本方法的调用顺序的安排,这些基本方法已经实现,而工厂方法则重点是创建,组装顺序则不关心。

    不同于抽象工厂的地方是:在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。

  Ø  小结

    u  装饰模式与建造者模式比较表

    此外无论是建造模式还是装饰模式,以及其他的模式,我们几乎都能看到一个抽象出来的东西,就是抽象类或者接口,那么这两者又有什么区别呢,我们下一篇来讲述。


http://blog.csdn.net/u010955843/article/details/24880281


原创粉丝点击