2.5.1 定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
2.5.2 结构图
Builder是为创建一个Product对象的各个部件指定的抽象接口。ConcreteBuilder是具体建造者,实现Builder接口,构造和装配各个部件。Product是产品,Director是指挥者,它是构建一个使用Builder接口的对象。
2.5.3 模拟场景
例如一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象,它是由CPU、主板、硬盘、显卡、机箱等组装而成的,如果此时让采购员一台一台电脑去组装的话真是要累死采购员了,这里就可以采用建造者模式来解决这个问题,我们可以把电脑的各个组件的组装过程封装到一个建造者类对象里,建造者只要负责返还给客户端全部组件都建造完毕的产品对象就可以了。然而现实生活中也是如此的,如果公司要采购一批电脑,此时采购员不可能自己去买各个组件并把它们组织起来,此时采购员只需要像电脑城的老板说自己要采购什么样的电脑就可以了,电脑城老板自然会把组装好的电脑送到公司。
2.5.4 代码实现
using System; using System.Collections; using System.Collections.Generic; namespace BuilderPattern { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } } public class Computer { //电脑组件集合 private 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 interface IBuilder { //装CPU void BuildPartCPU(); //装主板 void BuildPartMainBoard(); //装硬盘、电源等组件,这里省略 //获得组装好的电脑 Computer GetComputer(); } /// <summary> /// 具体的创建者,这个场景为具体的某个装机人:例如装机小王 /// </summary> public class ConcretBuilder1 : IBuilder { Computer computer = new Computer(); public void BuildPartCPU() { computer.Add("CPU1"); } public void BuildPartMainBoard() { computer.Add("MainBoard1"); } public Computer GetComputer() { return computer; } } /// <summary> /// 具体的创建者,这个场景为具体的某个装机人:例如装机小李 /// </summary> public class ConcretBuilder2 : IBuilder { Computer computer = new Computer(); public void BuildPartCPU() { computer.Add("CPU2"); } public void BuildPartMainBoard() { computer.Add("MainBoard2"); } public Computer GetComputer() { return computer; } } /// <summary> /// 建造者中的指挥者,这个场景就是电脑店的老板 /// </summary> public class Director { //组装电脑 public void Construct(IBuilder builder) { builder.BuildPartCPU(); builder.BuildPartMainBoard(); } } }
2.5.5 实现要点
1)在建造者模式中,指挥者是直接与客户端打交道的,指挥者将客户端创建产品的请求划分为对各个部件的建造请求,再将这些请求委派到具体建造者角色,具体建造者角色是完成具体产品的构建工作的,却不为客户所知道。
2)建造者模式主要用于“分步骤来构建一个复杂的对象”,其中“分步骤”是一个固定的组合过程,而复杂对象的各个部分是经常变化的(也就是说电脑的内部组件是经常变化的,这里指的的变化如硬盘的大小变了,CPU由单核变双核等)。
3)产品不需要抽象类,由于建造模式的创建出来的最终产品可能差异很大,所以不大可能提炼出一个抽象产品类。
4)在前面文章中介绍的抽象工厂模式解决了“系列产品”的需求变化,而建造者模式解决的是 “产品部分” 的需要变化。
5)由于建造者隐藏了具体产品的组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。