在软件系统中,有时须要建立一个复杂对象,而且这个复杂对象由其各部分子对象经过必定的步骤组合而成。设计模式
例如一个采购系统中,若是须要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象,它是由CPU、主板、硬盘、显卡、机箱等组装而成的,若是此时让采购员一台一台电脑去组装的话真是要累死采购员了,这里就能够采用建造者模式来解决这个问题,咱们能够把电脑的各个组件的组装过程封装到一个建造者类对象里,建造者只要负责返还给客户端所有组件都建造完毕的产品对象就能够了。然而现实生活中也是如此的,若是公司要采购一批电脑,此时采购员不可能本身去买各个组件并把它们组织起来,此时采购员只须要像电脑城的老板说本身要采购什么样的电脑就能够了,电脑城老板天然会把组装好的电脑送到公司。ide
1、 建造者(Builder)模式ui
将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。spa
建造者模式使得建造代码与表示代码的分离,可使客户端没必要知道产品内部组成的细节,从而下降了客户端与具体产品之间的耦合度。设计
2、 建造者模式的类图3d
3、 建造者模式的实现code
在这个例子中,电脑城的老板是直接与客户(也就是指采购员)联系的,然而电脑的组装是由老板指挥装机人员去把电脑的各个部件组装起来,真真负责建立产品(这里产品指的就是电脑)的人就是电脑城的装机人员。理清了这个逻辑过程以后,下面就具体看下如何用代码来表示这种现实生活中的逻辑过程:对象
using System; using System.Collections.Generic; /// <summary> /// 以组装电脑为例子 /// 每台电脑的组成过程都是一致的,可是使用一样的构建过程能够建立不一样的表示(便可以组装成不同的电脑,配置不同) /// 组装电脑的这个场景就能够应用建造者模式来设计 /// </summary> namespace BuilderPattern { /// <summary> /// 客户类 /// </summary> class Customer { static void Main(string[] args) { // 客户找到电脑城老板说要买电脑,这里要装两台电脑 // 建立指挥者和构造者 var director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); // 老板叫员工去组装第一台电脑 director.Construct(b1); // 组装完,组装人员搬来组装好的电脑 Computer computer1 = b1.GetComputer(); computer1.Show(); // 老板叫员工去组装第二台电脑 director.Construct(b2); Computer computer2 = b2.GetComputer(); computer2.Show(); Console.Read(); } } /// <summary> /// 小王和小李难道会自愿地去组装嘛,谁不想休息的,这必须有一我的叫他们去组装才会去的 /// 这我的固然就是老板了,也就是建造者模式中的指挥者 /// 指挥建立过程类 /// </summary> public class Director { // 组装电脑 public void Construct(Builder builder) { builder.BuildPartCpu(); builder.BuildPartMainBoard(); } } /// <summary> /// 电脑类 /// </summary> public class Computer { // 电脑组件集合 private readonly IList<string> _parts = new List<string>(); // 把单个组件添加到电脑组件集合中 public void Add(string part) { _parts.Add(part); } public void Show() { Console.WriteLine("电脑开始在组装......."); foreach (string part in _parts) { Console.WriteLine("组件" + part + "已装好"); } Console.WriteLine("电脑组装好了"); } } /// <summary> /// 抽象建造者,这个场景下为 "组装人" ,这里也能够定义为接口 /// </summary> public abstract class Builder { // 装CPU public abstract void BuildPartCpu(); // 装主板 public abstract void BuildPartMainBoard(); // 固然还有装硬盘,电源等组件,这里省略 // 得到组装好的电脑 public abstract Computer GetComputer(); } /// <summary> /// 具体建立者,具体的某我的为具体建立者,例如:装机小王啊 /// </summary> public class ConcreteBuilder1 : Builder { readonly Computer _computer = new Computer(); public override void BuildPartCpu() { _computer.Add("CPU1"); } public override void BuildPartMainBoard() { _computer.Add("Main board1"); } public override Computer GetComputer() { return _computer; } } /// <summary> /// 具体建立者,具体的某我的为具体建立者,例如:装机小李啊 /// 又装另外一台电脑了 /// </summary> public class ConcreteBuilder2 : Builder { readonly Computer _computer = new Computer(); public override void BuildPartCpu() { _computer.Add("CPU2"); } public override void BuildPartMainBoard() { _computer.Add("Main board2"); } public override Computer GetComputer() { return _computer; } } }
上面代码中都有详细的注释代码,这里就不过多解释,你们能够参考代码和注释来与现实生活中的例子作对比,下图展现了上面代码的运行结果:blog
电脑开始在组装…… 组件CPU1已装好 组件Main board1已装好 电脑组装好了 电脑开始在组装…… 组件CPU2已装好 组件Main board2已装好 电脑组装好了
4、 .NET 中建造者模式的实现接口
前面的设计模式在.NET类库中都有相应的实现,那在.NET 类库中,是否也存在建造者模式的实现呢? 然而对于疑问的答案是确定的,在.NET 类库中,System.Text.StringBuilder(存在mscorlib.dll程序集中)就是一个建造者模式的实现。不过它的实现属于建造者模式的演化,此时的建造者模式没有指挥者角色和抽象建造者角色,StringBuilder类即扮演着具体建造者的角色,也同时扮演了指挥者和抽象建造者的角色,此时建造模式的实现以下:
using System; using System.Collections.Generic; /// <summary> /// 建造者模式的演变 /// 省略了指挥者角色和抽象建造者角色 /// 此时具体建造者角色扮演了指挥者和建造者两个角色 /// </summary> public class Builder { // 具体建造者角色的代码 private readonly Product _product = new Product(); public void BuildPartA() { _product.Add("PartA"); } public void BuildPartB() { _product.Add("PartB"); } public Product GetProduct() { return _product; } // 指挥者角色的代码 public void Construct() { BuildPartA(); BuildPartB(); } } /// <summary> /// 产品类 /// </summary> public class Product { // 产品组件集合 private readonly IList<string> _parts = new List<string>(); // 把单个组件添加到产品组件集合中 public void Add(string part) { _parts.Add(part); } public void Show() { Console.WriteLine("产品开始在组装......."); foreach (string part in _parts) { Console.WriteLine("组件" + part + "已装好"); } Console.WriteLine("产品组装完成"); } } // 此时客户端也要作相应调整 class Client { private static Builder _builder; static void Main(string[] args) { _builder = new Builder(); _builder.Construct(); Product product = _builder.GetProduct(); product.Show(); Console.Read(); } }
5、 建造者模式的分析
建造模式的实现要点:
6、 总结
到这里,建造者模式的介绍就结束了,建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的一样的构建过程能够建立不一样的表示。建造者模式的本质是使组装过程(用指挥者类进行封装,从而达到解耦的目的)和建立具体产品解耦,使咱们不用去关心每一个组件是如何组装的。