建造者模式
来源:互联网 发布: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.多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,可以采用
- Builder 建造者模式
- 建造者模式
- 设计模式-------建造者
- 建造者模式
- 建造者模式(Builder)
- 建造者模式(Builder)
- 建造者模式
- 建造者模式 - builder
- 建造者模式
- Builder建造者模式
- 建造者模式(Builder)
- 建造者模式(builder)
- 建造者模式
- java建造者模式
- 建造者模式
- 建造者模式
- 建造者模式(Builder)
- 建造者模式
- 概率系列问题(二)
- String类不可变性的好处
- 第六周项目3-用多文件组织多个类的程序
- 使用MFC CImage类绘制PNG图片时遇到的问题
- 基础类的DSP/BIOS API调用
- 建造者模式
- 细说豹子头林冲
- 使用freemarker导出Word
- Web Service 一些对外公开的网络服务接口
- android 开发六层全解释--转自合并老罗博客
- PCA主元分析法人脸识别概述性小结
- hibernate一对一单向外键关联(Annatation)
- BAT指令收集
- 麻省理工学院《算法导论》(MIT - Introduction to Algorithms)