1. 意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2.适用性
在以下情况使用Builder模式
当创建复杂对象的算法应该独立与该对象的组成部分及他们的装配方式的时候
当构造过程必须允许被构造的对象有不同的表示时
3.结构图
Builder 模式中主要有三个角色
Director, Builder, Product
抽象的Builder定义了装配的算法或步骤,而具体的生成器则实现了这些算法或步骤
因此,调用者(Director)调用不同的Builder就可以产生不同的内容的对象
4.Builder与Abstract Factory
区别很明显,Builder模式返回一个对象,不同的Builder生成的对象仅仅是“内容“不同,Builder模式抽象出的是复杂对象构建的“步骤”
Abstract Factory关注的是一组对象,Abstract Factory模式抽象出的是一组对象中的共性 - 产品系列
5. 代码
关键点1 Product 对象的内部组成部分应该是public的,这样Builder才可以修改他们
关键点2 抽象的Builder定义了Product对象的组装步骤,只需要子类继承即可
关键点3 Directory指定了这些步骤的次序
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Builder_1 { class Program { static void Main(string[] args) { Product product = new Director().ConstructProduct(new BuilderA()); Console.WriteLine(product.Message); } } class Product { public string Content1 { get; set; } public string Content2 { get; set; } public string Content3 { get; set; } public string Message { get { return Content1 + Content2 + Content3; } } } abstract class Builder { public abstract void BuildContent1(); public abstract void BuildContent2(); public abstract void BuildContent3(); public abstract Product GetProduct(); } class BuilderA : Builder { private Product product = new Product(); public override void BuildContent1() { product.Content1 = "I am a "; } public override void BuildContent2() { product.Content2 = "C# "; } public override void BuildContent3() { product.Content3 = " programmer"; } public override Product GetProduct() { return product; } } class BuilderB : Builder { private Product product = new Product(); public override void BuildContent1() { product.Content1 = "I am a "; } public override void BuildContent2() { product.Content2 = "java "; } public override void BuildContent3() { product.Content3 = " architect"; } public override Product GetProduct() { return product; } } class Director { public Product ConstructProduct(Builder builder) { builder.BuildContent1(); builder.BuildContent2(); builder.BuildContent3(); return builder.GetProduct(); } } }
6. Builder模式的几种变体
1) 省略抽象的构建者
2) 省略指导者角色
3) 合并建造者角色和产品角色
特别要注意,Builder模式原本通过继承抽象的构建者来提供变化,一旦抽象的构建者消失,这个模式的变化点就只剩下一个了 -------
那就是构建过程的组合
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Builder_2 { class Program { static void Main(string[] args) { Product product = new Product(); product = product.BuildProductContent1("I "); product = product.BuildProductContent1("am "); product = product.BuildProductContent1("a "); product = product.BuildProductContent2("java "); product = product.BuildProductContent3(" architect"); Console.WriteLine(product.Message); } } sealed class Product { public string Content1 { get; set; } public string Content2 { get; set; } public string Content3 { get; set; } public string Message { get { return Content1 + Content2 + Content3; } } public Product BuildProductContent1(string text) { this.Content1 = this.Content1 + text; return this; } public Product BuildProductContent2(string text) { this.Content2 = this.Content2 + text; return this; } public Product BuildProductContent3(string text) { this.Content3 = this.Content3 + text; return this; } } }
上面的代码的调用者部分,很好的体现了Builder模式的精髓: 使得同样的构建过程可以创建不同的表示
构建过程BuilderProductContent1, 2, 3 没有变
可以通过构建过程调用的组合,可以让对象内容千变万化
这种写法是不是很像 .NET Framework 中的StringBuilder?