建造者模式

来源:互联网 发布:gcc编译器 linux 编辑:程序博客网 时间:2024/05/18 09:23

 

 

  上一篇博客谈到了自行车,这篇来进一步的深入的探讨一下。

 

  话说变化是永恒的,上一篇博客在模板方法模式的带领下,终于生产出来了一辆自行

 

车,但是客户又说了,我想要一辆自己随心所欲的自行车(就是一种自行车多种实现方

 

式),比如说先响铃、启动、停止或者先启动、停止、响铃,亦或停止、启动、响铃反正

 

都由客户自己控制,想什么顺序就什么顺序。  好吧,既然有需求就得重新来改。
  
 

  一般方法
 

  类图比较简单,在Bike中我们定义了一个SetSequence的方法,在此方法中定义一 个

 

动态数组,然后run()方法根据SetSequence定义的顺序完成指定的顺序动作。

 

 

上一篇的模板方法非常类似。接下来我们来看代码。

  

 

  先看Bike的源代码

 

public abstract class Bike    {        //这个参数是各个基本方法执行的顺序        private IList <string > sequence=new List<string>();        //首先,这个模型能够发动              public abstract void start();              //能发动,还能够停止               public abstract void stop();                //好屌啊,还可以响铃               public abstract void alarm();                //模型也应该会跑吧               public void run()            {                //通过一个循环,来遍历,谁在前,就先执行谁                for(int i=0;i<this.sequence.Count ;i++)                {                    string actionName=this.sequence[i];                    if(actionName.Equals("stop"))                    {                        this.stop ();                    }                    else if(actionName .Equals ("alarm"))                    {                        this.alarm ();                    }                    else if(actionName .Equals ("start"))                    {                        this.start ();                    }                }            }            //把传递过来的值传递到类内        public void setSequence(IList<string > sequence)        {            this.sequence =sequence ;        }    }



                                                     

   Bike的设计是这样的,setSequence方法使允许客户自己设置一个顺序,然后run

 

()方法来读取,通过遍历sequence中的字符串顺序,哪个字符串在先,就先执行哪个

 

方法。

 

 

 

  H1和H2模型的代码
    

public class H1:Bike     {        //H1型号的自行车鸣笛          public  override void alarm()        {            Console.WriteLine("H1鸣笛");         }                  //启动         public override void start()        {            Console.WriteLine("H1启动");          }                          //停止           public override void stop()          {             Console.WriteLine("H1停车");          }  }     //H2模型    public class H2:Bike     {        //H2型号的自行车鸣笛          public  override void alarm()        {            Console.WriteLine("H2鸣笛");         }                  //启动         public override void start()        {            Console.WriteLine("H2启动");          }                          //停止           public override void stop()          {             Console.WriteLine("H2停车");          }  }


 

        
            

 

  客户端代码
  

 static void Main(string[] args)        {            //客户来选择执行的顺序            H1 h1=new H1 ();            //定义一个动态数组,用来传递顺序            IList <string > sequence=new List <string >();            sequence .Add ("start");//客户要求先发动            sequence .Add ("stop");//然后响铃            sequence .Add ("alarm");//最后停止            h1.setSequence (sequence );            h1.run ();        }


          

  通过这种遍历的方法,我们满足了客户的需求,可是我们忽略了一个问题,我们目前

 

只完成了一个需求,但是自行车的执行顺序是要能够随意调整的,那该怎么办,我们一

 

次次的修改客户端吗?不可能,这时候想到了曾经学习过的工厂模式,我们来回顾一

 

下。

 

 

 

  工厂模式


   这就是工厂模式的类图,把不同的执行顺序都封装了然后到工厂中去生产,那么具体的实现是如何的呢,看下面的代码。

                                                                                                                                                                   

  HongQi类
      

public class HongQi     {        //自行车鸣笛          public  void alarm()        {            Console.WriteLine("鸣笛");        }        //启动         public  void start()        {            Console.WriteLine("启动");        }        //停止           public  void stop()        {            Console.WriteLine("停车");        }              public virtual HongQi run()        {            HongQi bike = new HongQi();            return bike;        }           }


 

 

  具体的两种顺序类
    

 //不同的启动顺序    public class Sequence1:HongQi     {               public override HongQi run()        {            HongQi hong1 = new HongQi();            base.stop();            base.alarm();            base.start();           return hong1 ;                    }    }    //启动顺序2    public class Sequence2 : HongQi     {       public override HongQi  run()        {            HongQi hong2 = new HongQi();            base.alarm();            base.start();            base.stop();            return hong2;        }    }


       

   

 工厂类
  

//根据不同的用户顺序来生产相应的自行车    public class BikeFactory    {        public static HongQi createBike(string sequence)        {           HongQi bike = null;            switch (sequence )            {                case "sequence1":                   bike=new Sequence1();                    break ;                case "sequence2":                    bike=new Sequence2 ();                    break ;            }            return bike ;        }    }


 

 

   客户端代码

   

static void Main(string[] args)        {            HongQi hong1 = BikeFactory.createBike("sequence1");            HongQi  h1 = hong1.run();        }



   

  建造者模式


  虽然通过简单工厂模式同样可以满足用户的需求,但我们分析一下,上面封装的不同

 

的顺序的类,如Sequence1和Sequence2代码都有重复;其次,我们学过排列组合,这才

 

是三个简单的功能的组合,功能多的话,那么用户的顺序可想而知,代码量将大大增

 

加;最后,可维护性也比较的低;那么就没有别的方法了吗?

 

  

  因为功能是一样的,只不过用户想法不同,执行的顺序不同而已,那么我们可以增加

 

一个组装类哈,就好比小时候玩过的堆方块似的,方块数目是一定的,可是不同的人堆

 

出来的效果不一样的。因此我们只要在增加一个组装的抽象类不就OK了吗。看类图。


 

 

    组装类BikeBuilder代码如下

    

public abstract class BikeBuilder    {        //建造一个模型,你给什么顺序,就生产什么顺序        public abstract  void setSequence(IList<string> sequence);        //设置完毕后,就可以直接拿到这个车辆模型        public abstract  H1 getbikeModel();    }


 

  H1的组装车间   

  

public class H1Builder:BikeBuilder    {        private H1 h1=new H1 ();        public override H1 getbikeModel()        {            return this.h1;        }        public override  void setSequence(IList<string> sequence)        {            this.h1.setSequence(sequence);        }    }


 

  客户端代码
                     

         

static void Main(string[] args)        {            //定义一个动态数组,用来传递顺序            IList<string> sequence = new List<string>();            sequence.Add("start");//客户要求先发动            sequence.Add("stop");//然后响铃            sequence.Add("alarm");//最后停止            H1Builder  h1builder = new H1Builder ();            //把顺序给这个Builder类            h1builder.setSequence(sequence);            //制造出一辆自行车来            H1 h1 = (H1)h1builder.getbikeModel();            h1.run();        }


 

 

   通过这种方法就彻底的把组装顺序,与功能相分离,减少了类的继承性,用户想要

 

增加新的车辆时,只需要更改客户端即可,但是又有问题出现了,如何能够做到当增加

 

新的需求时,不用来修改客户端呢 。就是所谓的把用的组装顺序,彻底的从客户端抽

 

离,好办,我们来增加一个指挥类。类图如下:

 

 

  

    这就是我们今天要说的建造者模式。

   

      简介
  

                定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同

 

的表示。

 

 

  优点

     

  封装性:客户端无需知道产品的细节

 

  容易扩展:当扩展的时候,只需要扩展Director即可

 

 

 使用场景

 

   1.相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用

   2.多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,可以采用

     

                            

 

                                                                            

 

 

0 0
原创粉丝点击