zoukankan      html  css  js  c++  java
  • 建造者模式(11)

    今天,我们来讲一下建造者模式。

    一、案例

    我们来用winform画一个小人,一个头,一个身体,两只手,两条腿。

    我们一般想到的代码如下:

     1         /// <summary>
     2         /// 画小人
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void pictureBox1_Paint(object sender, PaintEventArgs e)
     7         {
     8             Graphics gThin = e.Graphics;
     9             Pen p = new Pen(Color.Black, 2);
    10             gThin.DrawEllipse(p, 50, 20, 30, 30);
    11             gThin.DrawRectangle(p, 60, 50, 10, 50);
    12             gThin.DrawLine(p, 60, 50, 40, 100);
    13             gThin.DrawLine(p, 70, 50, 90, 100);
    14             gThin.DrawLine(p, 60, 100, 40, 150);
    15             gThin.DrawLine(p, 70, 100, 85, 150);
    16         }

    运行的效果:

    嗯,好,下面,我们再画一个稍微胖一点的小人。

    代码如下:

     1         private void pictureBox2_Paint(object sender, PaintEventArgs e)
     2         {
     3             Graphics gThin = e.Graphics;
     4             Pen p = new Pen(Color.Red, 2);
     5             gThin.DrawEllipse(p, 50, 20, 30, 30);
     6             gThin.DrawEllipse(p, 45, 50, 40, 50);
     7             gThin.DrawLine(p, 50, 50, 30, 100);
     8             gThin.DrawLine(p, 80, 50, 100, 100);
     9             gThin.DrawLine(p, 60, 100, 45, 150);
    10         }

    运行效果如下

    咦,我们好像少花了条腿哦。

    哈哈,像这样粗心的情况我们经常出现

    二、演绎

    1、第一步演绎

     1     /// <summary>
     2     /// 建造瘦小人的类
     3     /// </summary>
     4     class PersonThinBuilder
     5     {
     6         private Graphics _g;
     7         private Pen _p;
     8 
     9         public PersonThinBuilder(Graphics g, Pen p)
    10         {
    11             this._g = g;
    12             this._p = p;
    13         }
    14         /// <summary>
    15         /// 建造小人
    16         /// </summary>
    17         public void Build()
    18         {
    19             _g.DrawEllipse(_p, 50, 20, 30, 30);
    20             _g.DrawRectangle(_p, 60, 50, 10, 50);
    21             _g.DrawLine(_p, 60, 50, 40, 100);
    22             _g.DrawLine(_p, 70, 50, 90, 100);
    23             _g.DrawLine(_p, 60, 100, 40, 150);
    24             _g.DrawLine(_p, 70, 100, 85, 150);
    25         }
    26     }

    客户端

    1         private void pictureBox1_Paint(object sender, PaintEventArgs e)
    2         {
    3             Pen p = new Pen(Color.Black);
    4             Graphics gThin = e.Graphics;
    5             PersonThinBuilder ptb = new PersonThinBuilder(gThin, p);
    6             ptb.Build();
    7         }

    我们进行了第一步的改革,看了一下代码,将客户端的画小人的过程一直到了一个类中,客户端只需要调用这个类就可以了,但是,这仍然没有解决我们上面提到的问题,如果我们要画一个胖一点的小人,我们还需要建一个类,然后再写一遍创建过程,很难保证落下什么东西(比如:少了一只手也说不定哦)

    好,那么我们到底该如何解决呢?

    下面就是我们将要介绍的 建造者模式。

     建造者模式:将一个对象复杂的构建,与它的表示分离,使得同样的构建,可以创建不同的表示。

    如果我们使用了建造者模式,那么,用户只需要指定建造的类型就可以得到他们了,而具体的建造的细节和过程就不需要知道了。

    那么,我们画小人的案例该怎样使用建造者模式呢?我们一步步来分析。

    画小人,都需要画,头、身体、左手、右手、左腿、右腿。

    好,下面呢,我们就先来定义一个抽象的画小人的类,将这个过程固定住,不让任何人遗忘当中的任何一步。

     1     abstract class PersonBuilder
     2     {
     3         protected Graphics G;
     4         protected Pen P;
     5 
     6         protected PersonBuilder(Graphics g, Pen p)
     7         {
     8             G = g;
     9             P = p;
    10         }
    11 
    12         public abstract void BuildHead();
    13         public abstract void BuildBody();
    14         public abstract void BuildArmLeft();
    15         public abstract void BuildArmRight();
    16         public abstract void BuildLegLeft();
    17         public abstract void BuildLegRight();
    18     }

    然后,我们需要建造一个瘦一点的小人,我们可以让瘦一点的小人去继承这个抽象类。那么这个类就必须重写抽象类中的方法了,要不编译不通过的。所以,画小人就不会丢三落四了。

     1     class PersonThinBuilder : PersonBuilder
     2     {
     3         public PersonThinBuilder(Graphics g, Pen p) : base(g, p)
     4         {
     5         }
     6 
     7         public override void BuildHead()
     8         {
     9             G.DrawEllipse(P, 50, 20, 30, 30);
    10         }
    11 
    12         public override void BuildBody()
    13         {
    14             G.DrawRectangle(P, 60, 50, 10, 50);
    15         }
    16 
    17         public override void BuildArmLeft()
    18         {
    19             G.DrawLine(P, 60, 50, 40, 100);
    20         }
    21 
    22         public override void BuildArmRight()
    23         {
    24             G.DrawLine(P, 70, 50, 90, 100);
    25         }
    26 
    27         public override void BuildLegLeft()
    28         {
    29             G.DrawLine(P, 60, 100, 40, 150);
    30         }
    31 
    32         public override void BuildLegRight()
    33         {
    34             G.DrawLine(P, 70, 100, 85, 150);
    35         }
    36     }

    同理,胖子小人类也用上面的方式,继承抽象类,代码差不多,就不在写了。

    这样就完事了吗?如果完事了的话,那么我在客户端调用的时候,还是需要调用类里面的方法,万一哪一个方法没有调用,也就会出现丢三落四的情况了,这根本没有解决问题呀。所以,到这里,我们还没有完事呢。

    建造者模式还有一个非常重要的类,指挥者类。指挥者类是用来控制建造过程的,同时它也是隔离用户与建造过程的关联的。

    好,下面我们来写一个指挥者类。

     1     class PersonDirector
     2     {
     3         private PersonBuilder pb;
     4         //用户告诉指挥者,我需要什么样的小人
     5         public PersonDirector(PersonBuilder pb)
     6         {
     7             this.pb = pb;
     8         }
     9         //根据用户的选择建造小人
    10         public void CreatePerson()
    11         {
    12             pb.BuildHead();
    13             pb.BuildBody();
    14             pb.BuildArmLeft();
    15             pb.BuildArmRight();
    16             pb.BuildLegLeft();
    17             pb.BuildLegRight();
    18         }
    19     }

    这样,指挥者类写好了。其实指挥者类就是根据用户的选择,来一步一步的建造小人,而建造的过程在指挥者里面已经完成了,用户就不需要知道了。

    那么,客户端就是这样的了。

    1         private void pictureBox1_Paint(object sender, PaintEventArgs e)
    2         {
    3             //瘦小人
    4             PersonBuilder pb = new PersonThinBuilder(e.Graphics, new Pen(Color.Black));
    5             //告诉建造者,我要创建一个瘦小人
    6             PersonDirector pd = new PersonDirector(pb);
    7             //开始创建
    8             pd.CreatePerson();
    9         }

    ok,这样就成功的将我们的案例用建造者模式构建出来了。

    好了,建造者模式今天就讲到这里了,下篇博文我们将 观察者模式


    本系列将持续更新,喜欢的小伙伴可以点一下关注和推荐,谢谢大家的支持。

  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/xiaomowang/p/6322026.html
Copyright © 2011-2022 走看看