友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

8. 建造者模式

8.1. 定义

根据 GoF 的著名著作 《设计模式》,建造者模式的定义如下:

建造者模式(Builder)

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

— Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
《设计模式》

8.2. 类图

Diagram

如果你需要将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示的意图时,我们需要应用于一个设计模式,‘建造者(Builder)模式’,又叫生成器模式。建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需知道了。

是为创建一个Product对象的各个部件指定的抽象接口。

它是具体建造者,实现Builder接口,构造和装配各个部件。

它是构建一个使用Builder接口的对象。

它主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。

代码 57. builder/Builder.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.diguage.didp.builder;

/**
 * Builder 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public abstract class Builder {
  public abstract void buildPartA();

  public abstract void buildPartB();

  public abstract Product getResult();
}
代码 58. builder/ConcreteBuilder.java 类
 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
package com.diguage.didp.builder;

/**
 * ConcreteBuilder 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteBuilder extends Builder {
  private Product product = new Product();

  @Override
  public void buildPartA() {
    product.add("部件A");
  }

  @Override
  public void buildPartB() {
    product.add("部件B");
  }

  @Override
  public Product getResult() {
    return product;
  }
}
代码 59. builder/Director.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.diguage.didp.builder;

/**
 * Director 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class Director {
  public void construct(Builder builder) {
    builder.buildPartA();
    builder.buildPartB();
  }
}
代码 60. builder/Product.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.diguage.didp.builder;

import java.util.ArrayList;
import java.util.List;

/**
 * Product 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class Product {
  List<String> parts = new ArrayList<String>();

  public void add(String part) {
    parts.add(part);
  }

  public void show() {
    System.out.println("产品创建---");
    parts.forEach(System.out::println);
  }
}
代码 61. builder/Client.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.diguage.didp.builder;

/**
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-25 21:00:03
 */
public class Client {
  public static void main(String[] args) {
    Director director = new Director();
    Builder builder = new ConcreteBuilder();
    director.construct(builder);
    Product product = builder.getResult();
    product.show();
  }
}

8.3. 常见示例

  1. Lombok 的 @Builder

  2. java.lang.StringBuilder.append(*)

  3. java.sql.PreparedStatement