定 义:将一个复杂对象的构建与它的表示分离,使得同一构建过程可以创建不同的表示。
结构图:
产品类:
class Product { //部件集合 List<string> parts = new List<string>(); /// <summary> /// 添加部件 /// </summary> /// <param name="part"></param> public void Add(string part) { parts.Add(part); } public void Show() { Console.WriteLine(" 产品 创建--------"); foreach (var part in parts) { Console.WriteLine(part); } } }
抽象建造者类:
abstract class Builder { public abstract void BuilderPartA(); //组装部件1 public abstract void BuilderPartB(); //组装部件2 public abstract Product GetResult(); //返回组装好的产品 }
具体建造者类:
/// <summary> /// 具体建造者类1 /// </summary> class ConcreteBuilder1 : Builder { private Product product = new Product(); public override void BuilderPartA() { product.Add("部件A"); } public override void BuilderPartB() { product.Add("部件B"); } public override Product GetResult() { return product; } } /// <summary> /// 具体建造者类2 /// </summary> class ConcreteBuilder2 : Builder { private Product product = new Product(); public override void BuilderPartA() { product.Add("部件X"); } public override void BuilderPartB() { product.Add("部件Y"); } public override Product GetResult() { return product; } }
指挥者类:
class Director { public void Construct(Builder builder) { builder.BuilderPartA(); builder.BuilderPartB(); } }
客户端代码:
Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); director.Construct(b1); //指挥者用ConcreteBuilder1的方法来创建产品 Product p1 = b1.GetResult(); p1.Show(); director.Construct(b2); //指挥者用ConcreteBuilder2的方法来创建产品 Product p2 = b2.GetResult(); p2.Show();
优点:
•用户只需要指定要建造的类型就可以得到它们,而具体的建造过程和细节不需要知道。
•建造代码与表示相分离,如果要改变一个产品的内部表示,只要再定义一个新的具体的建造者就可以了。
•建造过程由指挥者来控制,建造细节由一个抽象类来控制,对于实现建造细节的具体类来说,不会遗漏某一个步骤。
缺点:
•产品的构造组件被定义在Builder,增加新的产品的一个细节需要修改Builder,违背了“开闭原则”。
应用情景:
•当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
•当复杂对象的部件相对稳定,不会发生变化时。