建造者模式
概述
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
结构图

代码实现
传统建造者
产品类
public class Product0 { IList<string> parts = new List<string>(); public void Add(string part) { parts.Add(part); } public void Show() { Console.WriteLine("\n产品 创建 ----"); foreach (string part in parts) { Console.WriteLine(part); } } }
建造者类
public abstract class Builder { public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product0 GetResult(); }
public class ConcreteBuilder1 : Builder { private Product0 product = new Product0(); public override void BuildPartA() { product.Add("部件A"); } public override void BuildPartB() { product.Add("部件B"); } public override Product0 GetResult() { return product; } }
public class ConcreteBuilder2 : Builder { private Product0 product = new Product0(); public override void BuildPartA() { product.Add("部件X"); } public override void BuildPartB() { product.Add("部件Y"); } public override Product0 GetResult() { return product; } }
指挥类
public class Director { public void Construct(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } }
客户端
static void Main(string[] args) { Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); director.Construct(b1); Product0 p1 = b1.GetResult(); p1.Show(); director.Construct(b2); Product0 p2 = b2.GetResult(); p2.Show(); Console.Read(); }
运行结果

传统建造者改进型
产品类
public class Product1 { Dictionary<string, string> parts = new Dictionary<string, string>(); public Product1(Dictionary<string, string> parts) { this.parts = parts; } public void Show() { Console.WriteLine("\n产品 展示 ----"); foreach (string key in parts.Keys) { Console.WriteLine(key + ":" + parts[key]); } } }
建造者类
public interface IBuilder { Product1 Build(); }
public class ConcreteIBuilder1 : IBuilder { Dictionary<string, string> parts = new Dictionary<string, string>(); public Product1 Build() { return new Product1(parts); } public ConcreteIBuilder1 SetPart1(string str) { parts["part1"] = str; return this; } public ConcreteIBuilder1 SetPart2(string str) { parts["part2"] = str; return this; } public ConcreteIBuilder1 SetPart3(string str) { parts["part3"] = str; return this; } }
public class ConcreteIBuilder2 : IBuilder { Dictionary<string, string> parts = new Dictionary<string, string>(); public Product1 Build() { return new Product1(parts); } public ConcreteIBuilder2 SetPart11(string str) { parts["part11"] = str; return this; } public ConcreteIBuilder2 SetPart22(string str) { parts["part22"] = str; return this; } }
客户端
static void Main(string[] args) { Product1 p1 = new ConcreteIBuilder1() .SetPart1("值1") .SetPart2("值2") .SetPart3("值3") .Build(); p1.Show(); Product1 p2 = new ConcreteIBuilder2() .SetPart11("值11") .SetPart22("值22") .Build(); p2.Show(); Console.Read(); }
运行结果

内部类建造者
产品和建造者类
public class Product2 { Builder builder; private Product2(Builder builder) { this.builder = builder; } public void Operation() { Console.WriteLine(builder.Parameter1); Console.WriteLine(builder.Parameter2); Console.WriteLine(builder.Parameter3); } //建造者在类的内部 public class Builder { private string parameter1; private string parameter2; private string parameter3; public string Parameter1 => parameter1; public string Parameter2 => parameter2; public string Parameter3 => parameter3; public Product2 Build() { if (string.IsNullOrWhiteSpace(parameter1)) { throw new Exception("parameter1未赋值"); } if (string.IsNullOrWhiteSpace(parameter2)) { throw new Exception("parameter2未赋值"); } if (string.IsNullOrWhiteSpace(parameter3)) { throw new Exception("parameter3未赋值"); } return new Product2(this); } public Builder SetParameter1(string str) { this.parameter1 = str; return this; } public Builder SetParameter2(string str) { this.parameter2 = str; return this; } public Builder SetParameter3(string str) { this.parameter3 = str; return this; } } }
客户端
static void Main(string[] args) { Product2 product2 = new Product2.Builder() .SetParameter1("值1") .SetParameter2("值2") .SetParameter3("值3") .Build(); product2.Operation(); Console.Read(); }
运行结果

优势
封装性好,构建和表示分离。
扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
使用场景
建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用
相同的方法,不同的执行顺序,产生不同的结果。
多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
缺陷
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

浙公网安备 33010602011771号