建造者模式——将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式同样是为了解决对象创建的低耦合而设计的模式,不过它有一些不同,那就是在于创建一系列对象时有序的,不可缺少的。如果用了建造者模式,那么用户只需指定需要建造的类型就可以得到它们,而建造的过程和细节就不需要知道了。
怎样运用建造者模式,有以下几个步骤:
1.Product类,既然是建造,那么必须有产品吧,这里定义了一个产品类,它有多个部件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 产品类 3 /// </summary> 4 public class Product 5 { 6 //创建一个包含产品的集合 7 readonly IList<string> _parts = new List<string>(); 8 9 /// <summary> 10 /// 给集合添加产品 11 /// </summary> 12 /// <param name="part"></param> 13 public void Add(string part) 14 { 15 _parts.Add(part); 16 } 17 18 /// <summary> 19 /// 创建并展示产品 20 /// </summary> 21 public void Show() 22 { 23 foreach (var part in _parts) 24 { 25 //在这里输出并展示产品 26 } 27 } 28 }
2.Builder类,产品有了,要开始建造了,别急,首先需要定义一个规范去有序的创建,Builder是一个抽象类,定义了创建产品的方法和一个得到产品的方法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 建造抽象类 3 /// 定义由子类去实现的抽象方法 4 /// 定义由子类去实现的得到建造完成的产品结果的抽象方法 5 /// </summary> 6 public abstract class Builder 7 { 8 public abstract void BuilderA(); 9 public abstract void BuilderB(); 10 public abstract Product GetResult(); 11 }
3.ConcreteBuilder类,建造规范有了,那就具体去实现建造的方法了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class ConcreteBuilder1 : Builder 2 { 3 //创建一个产品对象 4 private readonly Product _product = new Product(); 5 6 /// <summary> 7 /// 给产品进行A组装 8 /// </summary> 9 public override void BuilderA() 10 { 11 _product.Add("部件A"); 12 } 13 14 /// <summary> 15 /// 给产品进行B组装 16 /// </summary> 17 public override void BuilderB() 18 { 19 _product.Add("部件B"); 20 } 21 22 /// <summary> 23 /// 返回组装完成的产品 24 /// </summary> 25 /// <returns>产品</returns> 26 public override Product GetResult() 27 { 28 return _product; 29 } 30 } 31 32 class ConcreteBuilder2 : Builder 33 { 34 //创建一个产品对象 35 private readonly Product _product = new Product(); 36 37 /// <summary> 38 /// 给产品进行A组装 39 /// </summary> 40 public override void BuilderA() 41 { 42 _product.Add("部件X"); 43 } 44 45 /// <summary> 46 /// 给产品进行B组装 47 /// </summary> 48 public override void BuilderB() 49 { 50 _product.Add("部件Y"); 51 } 52 53 /// <summary> 54 /// 返回组装完成的产品 55 /// </summary> 56 /// <returns>产品</returns> 57 public override Product GetResult() 58 { 59 return _product; 60 } 61 }
4.Derector类,建造的方法有了,谁去建造,怎么建造?由指挥者类去建造。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 指挥者类 3 /// </summary> 4 public class Diractor 5 { 6 /// <summary> 7 /// 指挥创建一耳光完整的对象 8 /// 不会遗漏 9 /// </summary> 10 /// <param name="builder"></param> 11 public void Construct(Builder builder) 12 { 13 builder.BuilderA(); 14 builder.BuilderB(); 15 } 16 }
5.客户端代码,好了,指挥者也有了,建造方法也有了,加入两个产品去建造下吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //创建指挥者对象 6 var diractor = new Diractor(); 7 //创建具体建造者1对象 8 Builder builder1=new ConcreteBuilder1(); 9 //指挥者指挥去创建产品1 10 diractor.Construct(builder1); 11 //创建完成,产品来接受 12 Product product1 = builder1.GetResult(); 13 //产品1进行展示 14 product1.Show(); 15 16 //创建具体建造者2对象 17 Builder builder2 = new ConcreteBuilder2(); 18 //指挥者指挥去创建产品2 19 diractor.Construct(builder2); 20 //创建完成,产品来接受 21 Product product2 = builder2.GetResult(); 22 //产品2进行展示 23 product2.Show(); 24 } 25 }
一个对象可能有多种算法,为了实现单一责任原则,那么算法的实现应该独立于该对象的组成和装配,那么建造者模式就适用于这种状况。
以上内容部分参考程杰的《大话设计模式》一书