c#设计模式(5)——建造者模式
一、引言
创建型设计模式,就是专门用来创建对象;创建对象的事儿全权由你负责,我就不操心了,有点想领导的感觉,命令下去,活都是工人的,至于是哪个人去做那些事,才是领导的责任。建造者模式,例如一个车间系统中,如果需要车间老板想要一批车辆时,在这个实际需求中,车辆就是一个复杂的对象,它是由车灯、车辆、机箱等组装而成的,如果此时让老板一台一台车去组装的话真是要累死老板了,这里就可以采用建造者模式来解决这个问题,我们可以把车辆的各个组件的组装过程封装到一个建造者类对象里,让工人去造不同的车,建造者只要负责返还给客户端全部组件都建造完毕的产品对象就可以了。至于老板,只需要让老板命令那些工人去造那些车就行了。
部分内容选自https://www.cnblogs.com/zhili/p/BuilderPattern.html,感觉写得很好,我只是自己总结成自己的东西。
二、介绍
在这个例子中,车间的老板是指挥工人去把车的各个部件组装起来,真真负责创建产品(这里产品指的就是车)的人就是车间工人。理清了这个逻辑过程之后,下面就具体看下如何用代码来表示这种现实生活中的逻辑过程:
1.首先得准备组成车的各个部件吧,也就是各个组成功能的类
/// <summary> /// 造车必备 工程师 /// </summary> public class Engine { public string Name { get; set; } } /// <summary> /// 造车组件 灯光 /// </summary> public class Light { public string Name { get; set; } } /// <summary> /// 造车组件 车轮 /// </summary> public class Wheels { public string Name { get; set; } } /// <summary> /// 成品车----需要 工程师、灯光、车轮 /// </summary> public class Car { public Engine Engine { get; set; } public Light Light { get; set; } public Wheels Wheels { get; set; } public string Name { get; set; } public Car(Engine engine, Light light, Wheels wheels) { } public Car() { } }
2.车组件都准备好了,那就让工人干咯,当然啦,造车流程大同小异,肯定要定义个抽象类来定义造车必要操作。
public class AbstractBuilderInfo { public string Name { get; set; } public int Age { get; set; } } /// <summary> /// 工人抽象 /// </summary> public abstract class AbstractBuilder :AbstractBuidlerInfo { public abstract void Engine(); public abstract void Wheels(); public abstract void Light(); public abstract Car Car(); }
3.现在就要让给个车间都准备好了,工人来操作吧,也就是真正的建造者。至于要造什么车,不同工人来造了。
/// <summary> /// 比亚迪工人 /// </summary> public class BuilderBYD : AbstractBuilder { private Engine _Engine = null; private Light _Light = null; private Wheels _Wheels = null; public override void Engine() { this._Engine = new Engine() { Name = "比亚迪工程师" }; Console.WriteLine("{0} build Engine", this.GetType().Name); } public override void Light() { this._Light = new Light() { Name = "比亚迪灯光" }; Console.WriteLine("{0} build Light", this.GetType().Name); } public override void Wheels() { this._Wheels = new Wheels() { Name = "比亚迪车辆" }; Console.WriteLine("{0} build Wheels", this.GetType().Name); } public override Car Car() { Console.WriteLine("组装 {0} {1} {2}", this._Engine, this._Light, this._Wheels); Console.WriteLine("{0} build 比亚迪汉", this.GetType().Name); return new Car(this._Engine, this._Light, this._Wheels) { Engine = this._Engine, Light = this._Light, Wheels = this._Wheels, Name = "比亚迪汉车" }; } }
/// <summary> /// 本田工人 /// </summary> public class BuilderBenz : AbstractBuilder { private Engine _Engine = null; private Light _Light = null; private Wheels _Wheels = null; public override void Engine() { this._Engine = new Engine() { Name = "本田工程师" }; Console.WriteLine("{0} build Engine", this.GetType().Name); } public override void Light() { this._Light = new Light() { Name = "本田灯光" }; Console.WriteLine("{0} build Light", this.GetType().Name); } public override void Wheels() { this._Wheels = new Wheels() { Name = "本田车辆" }; Console.WriteLine("{0} build Wheels", this.GetType().Name); } public override Car Car() { Console.WriteLine("组装 {0} {1} {2}", this._Engine, this._Light, this._Wheels); Console.WriteLine("{0} build 本田", this.GetType().Name); return new Car(this._Engine, this._Light, this._Wheels) { Engine = this._Engine, Light = this._Light, Wheels = this._Wheels, Name = "本田" }; } }
4. 现在由指挥者统一 来规范造车的步骤流程。
/// <summary> /// /造车子 执行者/管理者,构造函数传递一个工人进来造车 /// </summary> public class Director { private AbstractBuilder _abstractBuilder = null; public Director(AbstractBuilder abstractBuilder) { this._abstractBuilder = abstractBuilder; } /// <summary> /// 完全由管理者来控制 建造过程:建造顺序 /// </summary> /// <returns></returns> public Car GetCar() { _abstractBuilder.Engine(); _abstractBuilder.Light(); _abstractBuilder.Wheels(); return _abstractBuilder.Car(); } }
5.主函数来实现
建造这模式:建造者+管理者 , 建造者: 负责内部结构的构造,管理者:指挥建造者来构造内部结构的执行过程;指挥者可以构造出不同类型的复杂对象;给我什么类型的建造者我就建造出什么类型的复杂对象;Build 方法的都是建造者模式。
class Program { static void Main(string[] args) { //比亚迪工人造车 AbstractBuilder builderBYD = new BuilderBYD(); builderBYD.Engine(); builderBYD.Light(); builderBYD.Wheels(); builderBYD.Car(); //本田个人造车 AbstractBuilder builderBenz = new BuilderBenz(); builderBenz.Engine(); builderBenz.Light(); builderBenz.Wheels(); builderBenz.Car(); //管理着指挥工人造车 AbstractBuilder builder = new BuilderBYD(); Director director = new Director(builder); director.GetCar(); AbstractBuilder builder2 = new BuilderBenz(); director = new Director(builder2); director.GetCar(); } }
三、建造者模式的分析
介绍完了建造者模式的具体实现之后,让我们总结下建造模式的实现要点:
- 在建造者模式中,指挥者是直接与客户端打交道的,指挥者将客户端创建产品的请求划分为对各个部件的建造请求,再将这些请求委派到具体建造者角色,具体建造者角色是完成具体产品的构建工作的,却不为客户所知道。
- 建造者模式主要用于“分步骤来构建一个复杂的对象”,其中“分步骤”是一个固定的组合过程,而复杂对象的各个部分是经常变化的(也就是说电脑的内部组件是经常变化的,这里指的的变化如硬盘的大小变了,CPU由单核变双核等)。
- 产品不需要抽象类,由于建造模式的创建出来的最终产品可能差异很大,所以不大可能提炼出一个抽象产品类。
- 在前面文章中介绍的抽象工厂模式解决了“系列产品”的需求变化,而建造者模式解决的是 “产品部分” 的需要变化。
- 由于建造者隐藏了具体产品的组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。