设计模式-02.BUILDER(生成器)— 对象创建型模式

1 意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2 别名

3 动机

一个RTF(Rich Text Format)文档交换格式的阅读器应能将 RTF 转换为多种正文格式。该阅读器可以将 RTF 文档转换成普通 ASCII 文本或转换成一个能以交互方式编辑的正文窗口组件。但问题在于可能转换的数目是无限的。因此要能够很容易实现新的转换的增加,同时却不改变 RTF 阅读器。
图一

4 适用性

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

5 结构

图二

6 参与者

  • Builder(TextConverter)
    • 为创建一个 Product 对象的各个部件指定抽象接口。
  • ConcreteBuilder(ASCIIConverter、TeXConverter、TextWidgetConverter)
    • 实现Builder的接口以构造和装配该产品的各个部件;
    • 定义并明确它所创建的表示;
    • 提供一个检索产品的接口(例如,GetASCIIText和GetTextWidget)。
  • Director(RTFReader)
    • 构造一个使用Builder接口的对象。
  • Product(ASCIIText、TeXText、TextWidget)
    • 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程;
    • 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

7 协作

  • 客户创建 Director 对象,并用它所想要的 Builder 对象进行配置。
  • 一旦产品部件被生成,导向器就会通知生成器。
  • 生成器处理导向器的请求,并将部件添加到该产品中。
  • 客户从生成器中检索产品。

下面的交互图说明了Builder和Director是如何与一个客户协作的。
图二

8 效果

  • 它使你可以改变一个产品的内部表示
  • 它将构造代码和表示代码分开
  • 它使你可对构造过程进行更精细的控制

9 实现

  • 装配和构造接口
  • 为什么产品没有抽象类
  • 在 Builder 中缺省的方法为空

10 代码示例

  • Builder

    1
    2
    3
    4
    5
    6
    7
    8
    interface IBuilder
    {
    void BuildPart1();
    void BuildPart2();
    void BuildPart3();

    Product GetProduct();
    }
  • ConcreteBuilder

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    class Product1Builder:IBuilder
    {
    public void BuildPart1()
    {
    Console.WriteLine("Product1 Part1 Build Success!");
    }
    public void BuildPart2()
    {
    Console.WriteLine("Product1 Part2 Build Success!");
    }
    public void BuildPart3()
    {
    Console.WriteLine("Product1 Part3 Build Success!");
    }

    Product GetProduct()
    {
    return new Product("Product1");
    }
    }
    class Product2Builder:IBuilder
    {
    public void BuildPart1()
    {
    Console.WriteLine("Product2 Part1 Build Success!");
    }
    public void BuildPart2()
    {
    Console.WriteLine("Product2 Part2 Build Success!");
    }
    public void BuildPart3()
    {
    Console.WriteLine("Product2 Part3 Build Success!");
    }

    Product GetProduct()
    {
    return new Product("Product2");
    }
    }
  • Director

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Director
    {
    Product CreateProduct(IBuilder builder)
    {
    builder.BuildPart1();
    builder.BuildPart2();
    builder.BuildPart3();

    return builder.GetProduct();
    }
    }
  • Product

    1
    2
    3
    4
    5
    6
    7
    class Product
    {
    public Product(string name)
    {
    Console.WriteLine("产品名称:{name}");
    }
    }
  • Main

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Program
    {
    public static void Main(string[] args)
    {
    IBuilder builder=new Product1Builder();

    Director director=new Director();
    Product product=director.CreateProduct(builder);
    }
    }

11 已知应用

  • RTF转换器
  • ASP.NET CORE的MvcWebApplicationBuilder

12 相关模式

  • AbstractFactory 与 Builder 相似,因为它也可以创建复杂对象。主要的区别是 Builder 模式着重于一步步构造一个复杂对象。而AbstractFactory着重于多个系列的产品对象(简单的或是复杂的)。Builder 在最后的一步返回产品,而对于 AbstractFactory 来说,产品是立即返回的。
  • Composite 通常是用 Builder 生成的。
坚持原创技术分享,您的支持将鼓励我继续创作!