设计模式(构建者模式)
建造者设计模式详解
建造者模式(Builder Pattern)是一种创建型设计模式,它允许我们分步骤创建复杂对象。这种模式特别适合那些需要多个步骤才能构建出来的、有很多配置选项的对象。
为什么需要建造者模式?
想象一下,我们需要创建一个House
对象,这个房子有墙壁、门、窗户、屋顶等组件。传统方式可能是这样的:
House house = new House(4, 2, 6, true, "红砖", "木头", "瓷砖");
这种方式有几个问题:
- 参数过多:构造函数的参数太多,容易搞混
- 参数顺序:必须记住参数的准确顺序
- 可选参数:如果某些参数是可选的,可能需要创建多个构造函数
建造者模式如何解决这些问题?
建造者模式将对象的构造过程抽象为独立的步骤,每个步骤都可以被单独调用,最后一次性创建完整的对象。
图解建造者模式
让我们通过一个图例来理解建造者模式的结构:
┌───────────────┐ uses ┌───────────────┐
│ Client │───────────────▶│ Director │
└───────────────┘ └───────┬───────┘││ uses▼
┌───────────────┐ builds ┌───────────────┐
│ Product │◀───────────────│ Builder │
└───────────────┘ └───────┬───────┘││ implements▼┌───────────────┐│ConcreteBuilder│└───────────────┘
这个图解展示了以下组件:
- Product:最终要创建的复杂对象
- Builder:定义创建Product对象的抽象接口
- ConcreteBuilder:实现Builder接口的具体类
- Director:调用Builder接口创建最终的Product对象
建造房子的例子
让我们用建造房子作为例子,看看建造者模式如何工作:
创建过程
┌─────────────────────────────────┐
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │ ┌───────────┐
│ │ │ │ │ │ │ │ │ │
│ │墙壁 │───▶│门窗 │───▶│屋顶 │─┼────▶│ 完整房屋 │
│ │ │ │ │ │ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │ └───────────┘
│ │
└─────────────────────────────────┘
代码实现
下面是一个Java代码实现的例子:
// 1. 产品类
class House {private String foundation;private String walls;private String roof;private int windows;private int doors;private boolean hasGarage;private boolean hasSwimmingPool;private boolean hasGarden;public String toString() {return "House with " + walls + " walls, " + roof + " roof, " + windows + " windows, " + doors + " doors" + (hasGarage ? ", with garage" : ", without garage") +(hasSwimmingPool ? ", with swimming pool" : ", without swimming pool") +(hasGarden ? ", with garden" : ", without garden");}// Getter 方法...// 私有构造函数,只能通过Builder访问private House() {}// 静态内部Builder类public static class Builder {private House house;public Builder() {house = new House();}public Builder foundation(String foundation) {house.foundation = foundation;return this;}public Builder walls(String walls) {house.walls = walls;return this;}public Builder roof(String roof) {house.roof = roof;return this;}public Builder windows(int windows) {house.windows = windows;return this;}public Builder doors(int doors) {house.doors = doors;return this;}public Builder garage(boolean hasGarage) {house.hasGarage = hasGarage;return this;}public Builder swimmingPool(boolean hasSwimmingPool) {house.hasSwimmingPool = hasSwimmingPool;return this;}public Builder garden(boolean hasGarden) {house.hasGarden = hasGarden;return this;}public House build() {return house;}}
}// 2. 指导者类(可选)
class HouseDirector {public House constructLuxuryHouse(House.Builder builder) {return builder.foundation("混凝土").walls("砖墙").roof("瓦片屋顶").windows(8).doors(4).garage(true).swimmingPool(true).garden(true).build();}public House constructSimpleHouse(House.Builder builder) {return builder.foundation("混凝土").walls("砖墙").roof("简易屋顶").windows(4).doors(2).garage(false).swimmingPool(false).garden(false).build();}
}// 3. 客户端代码
public class BuilderDemo {public static void main(String[] args) {// 使用Builder直接构建House house1 = new House.Builder().walls("砖墙").roof("瓦片屋顶").windows(6).doors(2).garage(true).build();System.out.println("自定义房屋: " + house1);// 使用Director构建预定义房屋类型HouseDirector director = new HouseDirector();House luxuryHouse = director.constructLuxuryHouse(new House.Builder());House simpleHouse = director.constructSimpleHouse(new House.Builder());System.out.println("豪华房屋: " + luxuryHouse);System.out.println("简易房屋: " + simpleHouse);}
}
建造者模式的流程图
以下是建造者模式的实际工作流程图:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ (1) │ │ (2) │ │
│ Client │────────▶│ Builder │────────▶│ Product │
│ │ 创建 │ │ 构建 │ │
└─────────────┘ └──────┬──────┘ └─────────────┘││ (1.1) 设置属性│▼┌─────────────┐│ Director ││ (可选) │└─────────────┘
- 客户端创建一个Builder对象
- 客户端直接或通过Director配置Builder
- 客户端调用Builder的build()方法获取最终产品
建造者模式的优点
- 分步构建:可以一步一步创建复杂对象
- 流式接口:使用方法链提供流畅的API
- 参数清晰:每个方法名清晰表明设置的是什么属性
- 不变性:可以创建不可变对象
- 可选参数:轻松处理大量可选参数
建造者模式的应用场景
- 复杂对象创建:当对象有很多属性,特别是有可选属性时
- 不可变对象:需要创建不可变对象时
- 多步骤构建:对象需要多步骤才能完成构建时
- 配置对象:需要创建具有多种配置的对象时
现实世界中的建造者模式
Java中的几个常见例子:
StringBuilder
和StringBuffer
DocumentBuilder
在Java的XML处理中- Java 8中Stream API的链式调用
结论
建造者模式是一种强大的设计模式,尤其适合创建复杂对象。它将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式提高了代码的可读性、可维护性,并且提供了一种创建复杂对象的清晰方式。
当你面对具有许多属性的复杂对象时,考虑使用建造者模式,它可以让你的代码更加整洁和灵活。