建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式使得建造代码与表示代码的分离,可以使客户端不必知道产品内部组成的细节,从而降低了客户端与具体产品之间的耦合度,下面通过类图来帮助大家更好地理清建造者模式中类之间的关系。
建造者模式中主要有三类角色:
- Product产品类:
- Builder抽象建设者:规范产品的组建,一般是由子类实现。
- ConcreteBuilder具体建造者:实现抽象类定义的所有方法,并且返回一个组建好的对象。
- Director导演类:负责安排已有模板的顺序,然后告诉Builder开始建造。
具体实现
namespace ConsoleApplication1 { /// <summary> /// 产品类 /// </summary> public class Product { public void doSomething() { //独立业务处理 } } /// <summary> /// 抽象建造者 /// </summary> public abstract class Builder { //设置产品的不同部分,以获取不同的产品 public abstract void setPart(); //建造产品 public abstract Product buildProduct(); } public class ConcreteProduct : Builder { private Product product = new Product(); //设置产品零件 public override void setPart() { /* *产品内部的逻辑处理 */ } public override Product buildProduct() { return product; } } public class Director { private Builder builder = new ConcreteProduct(); public Product getAProduct() { builder.setPart(); /* * 设置不同的零件,产生不同的产品 */ return builder.buildProduct(); } } class Program { static void Main(string[] args) { Console.ReadLine(); } } }
建造者模式的优点
建造者模式具有以下优点:
- 封装性
使用建造者模式可以使客户端不必知道产品内部组成的细节。
- 建造者独立,容易扩展
建造者彼此间相互独立的,对系统的扩展非常有利。
- 便于控制细节风险
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
建造者模式的使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
- 产品类非常复杂,或者产品类中调用顺序不同产生了不同的效能。
- 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时。
一个构建汽车模式的范例:
完整类图如下:
具体代码如下:
View Code
namespace TempApplication { /// <summary> /// 车辆模型的抽象类 /// </summary> public abstract class CarModel { private List<string> sequence = new List<string>(); public List<string> Sequence { set { this.sequence = value; } } protected abstract void start(); protected abstract void stop(); protected abstract void alarm(); protected abstract void engineBoom(); public void run() { foreach (string item in sequence) { switch (item) { case "start": this.start(); //启动汽车 break; case "stop": this.stop(); //停止汽车 break; case "alarm": this.alarm(); //喇叭开始叫了 break; case "engine boom": this.engineBoom(); //引擎开始轰鸣 break; default: throw new Exception("未定义的操作流程"); } } } } public class BenzModel : CarModel { protected override void start() { Console.WriteLine("奔驰车跑起来是这个样子的..."); } protected override void stop() { Console.WriteLine("奔驰车应该这样停车..."); } protected override void alarm() { Console.WriteLine("奔驰车的喇叭声音是这个样子的..."); } protected override void engineBoom() { Console.WriteLine("奔驰车的引擎是这个声音的..."); } } public class BMWModel : CarModel { protected override void start() { Console.WriteLine("宝马车跑起来是这个样子的..."); } protected override void stop() { Console.WriteLine("宝马车应该这样停车..."); } protected override void alarm() { Console.WriteLine("宝马车的喇叭声音是这个样子的..."); } protected override void engineBoom() { Console.WriteLine("宝马车的引擎是这个声音的..."); } } /// <summary> /// 抽象汽车组装者 /// </summary> public abstract class CarBuilder { //建造一个模式,你要给我一个顺序要求,就是组装顺序 public abstract void setSuqence(List<string> sequence); //设置完毕顺序后,就可以直接拿到这个车辆模型 public abstract CarModel getCarModel(); } public class BenzBuilder : CarBuilder { private BenzModel benz = new BenzModel(); public override void setSuqence(List<string> sequence) { this.benz.Sequence = sequence; } public override CarModel getCarModel() { return this.benz; } } public class BMWBuilder : CarBuilder { private BMWModel bmw = new BMWModel(); public override void setSuqence(List<string> sequence) { this.bmw.Sequence = sequence; } public override CarModel getCarModel() { return this.bmw; } } /// <summary> /// 导演类 /// </summary> public class Director { private List<string> sequence = new List<string>(); private BenzBuilder benzBuilder = new BenzBuilder(); private BMWBuilder bmwBuilder = new BMWBuilder(); /// <summary> /// A类型的奔驰车模型,先start,然后stop,其他什么引擎、喇叭一概没有 /// </summary> /// <returns></returns> public BenzModel getABenzModel() { this.sequence.Clear(); //ABenzModel的执行顺序 this.sequence.Add("start"); this.sequence.Add("stop"); //按照顺序返回一个奔驰车 this.benzBuilder.setSuqence(this.sequence); return (BenzModel)this.benzBuilder.getCarModel(); } /// <summary> /// B类型的奔驰车模型,先发动引擎,然后启动,然后停止,没有喇叭 /// </summary> /// <returns></returns> public BenzModel getBBenzModel() { this.sequence.Clear(); this.sequence.Add("engine boom"); this.sequence.Add("start"); this.sequence.Add("stop"); this.benzBuilder.setSuqence(this.sequence); return (BenzModel)this.benzBuilder.getCarModel(); } /// <summary> /// C类型的宝马车模型,先按下喇叭,然后启动,然后停止 /// </summary> /// <returns></returns> public BMWModel getCBMWModel() { this.sequence.Clear(); this.sequence.Add("engine boom"); this.sequence.Add("start"); this.sequence.Add("stop"); this.bmwBuilder.setSuqence(this.sequence); return (BMWModel)this.bmwBuilder.getCarModel(); } /// <summary> /// D类型的宝马车只有一个功能,就是跑. /// </summary> /// <returns></returns> public BMWModel getDBMWModel() { this.sequence.Clear(); this.sequence.Add("start"); this.bmwBuilder.setSuqence(this.sequence); return (BMWModel)this.bmwBuilder.getCarModel(); } /* * 这里可以有很多方法,按你自己的喜欢的顺序来定义 */ } class Client { static void Main(string[] args) { Director director = new Director(); //A类型的奔驰车 director.getABenzModel().run(); //B类型的奔驰车 director.getBBenzModel().run(); //C类型的宝马车 director.getCBMWModel().run(); Console.Read(); } } }