设计模式之建造者模式
意图
建造者模式(Builder)是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。
使用建造者模式,用户就只需要指定需要建造的类型,具体的建造过程和细节并不需要知道。
建造者模式允许修改一个产品的内部表示。
它将构造和表示两块代码隔离开来。
它很好的控制了构建过程。
建造者模式流程说明:
- 客户端创建 Director 对象并配置它所需要的 Builder 对象。
- Director 负责通知 builder 何时建造 product 的部件。
- Builder 处理 director 的请求并添加 product 的部件。
- 客户端从 builder 处获得 product。
适用场景
- 使用建造者模式可避免 “重叠构造函数 (telescopic constructor)” 的出现。
- 当你希望使用代码创建不同形式的产品时, 可使用建造者模式。
- 使用建造者构造组合树或其他复杂对象。
结构
- 建造者 (Builder) 接口声明在所有类型建造者中通用的产品构造步骤。
- 具体建造者 (Concrete Builders) 提供构造过程的不同实现。 具体建造者也可以构造不遵循通用接口的产品。
- 产品 (Products) 是最终生成的对象。 由不同建造者构造的产品无需属于同一类层次结构或接口。
- 主管 (Director) 类定义调用构造步骤的顺序, 这样你就可以创建和复用特定的产品配置。
- 客户端 (Client) 必须将某个建造者对象与主管类关联。 一般情况下, 你只需通过主管类构造函数的参数进行一次性关联即可。 此后主管类就能使用建造者对象完成后续所有的构造任务。 但在客户端将建造者对象传递给主管类制造方法时还有另一种方式。 在这种情况下, 你在使用主管类生产产品时每次都可以使用不同的建造者。
【Product】产品类,由多个部件构成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Product { List<String> parts = new ArrayList<String>();
public void AddPart(String part) { parts.add(part); }
public void show() { System.out.println("============== 产品创建 =============="); for (String part : parts) { System.out.println(part); } } }
|
【Builder】
抽象建造者,确定产品由 ABC 三个部件构成,并声明一个得到产品建造后结果的方法 getResult。
1 2 3 4 5 6
| interface Builder { public void buildPartA(); public void buildPartB(); public void buildPartC(); public Product getResult(); }
|
【ConcreteBuilder】
实现 Builder 接口中的具体方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class ConcreteBuilder implements Builder { private Product product = new Product();
@Override public void buildPartA() { product.AddPart("部件A"); }
@Override public void buildPartB() { product.AddPart("部件B"); }
@Override public void buildPartC() { product.AddPart("部件C"); }
@Override public Product getResult() { return product; } }
|
【Director】
指挥者类,指挥建造 Product 的过程(控制构建各部分组件的顺序)。
1 2 3 4 5 6 7
| class Director { public void construct(Builder builder) { builder.buildPartC(); builder.buildPartA(); builder.buildPartB(); } }
|
【客户端】
用户并不需要知道具体的建造过程,只需指定建造 Product 具体类型。
1 2 3 4 5 6 7 8 9 10
| public class BuilderPattern { public static void main(String[] args) { Director director = new Director(); Builder builder = new ConcreteBuilder();
director.construct(builder); Product product = builder.getResult(); product.show(); } }
|
【输出】
1 2 3 4
| ============== 产品创建 ============== 部件C 部件A 部件B
|
伪代码
下面关于建造者模式的例子演示了你可以如何复用相同的对象构造代码来生成不同类型的产品——例如汽车 (Car)——及其相应的使用手册 (Manual)。
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
class Car is
class Manual is
interface Builder is method reset() method setSeats(...) method setEngine(...) method setTripComputer(...) method setGPS(...)
class CarBuilder implements Builder is private field car:Car
constructor CarBuilder() is this.reset()
method reset() is this.car = new Car()
method setSeats(...) is
method setEngine(...) is
method setTripComputer(...) is
method setGPS(...) is
method getProduct():Car is product = this.car this.reset() return product
class CarManualBuilder implements Builder is private field manual:Manual
constructor CarManualBuilder() is this.reset()
method reset() is this.manual = new Manual()
method setSeats(...) is
method setEngine(...) is
method setTripComputer(...) is
method setGPS(...) is
method getProduct():Manual is
class Director is private field builder:Builder
method setBuilder(builder:Builder) this.builder = builder
method constructSportsCar(builder: Builder) is builder.reset() builder.setSeats(2) builder.setEngine(new SportEngine()) builder.setTripComputer(true) builder.setGPS(true)
method constructSUV(builder: Builder) is
class Application is
method makeCar() is director = new Director()
CarBuilder builder = new CarBuilder() director.constructSportsCar(builder) Car car = builder.getProduct()
CarManualBuilder builder = new CarManualBuilder() director.constructSportsCar(builder)
Manual manual = builder.getProduct()
|
案例
使用示例: 建造者模式是 Java 世界中的一个著名模式。 当你需要创建一个可能有许多配置选项的对象时, 该模式会特别有用。
建造者在 Java 核心程序库中得到了广泛的应用:
识别方法: 建造者模式可以通过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 建造者方法通常支持方法链 (例如 someBuilder->setValueA(1)->setValueB(2)->create()
)
与其他模式的关系
参考资料