建造者模式(Builder Pattern)是一种创建型设计模式,它允许我们分步骤创建复杂对象。这种模式特别适合那些需要多个步骤才能构建出来的、有很多配置选项的对象。
想象一下,我们需要创建一个House
对象,这个房子有墙壁、门、窗户、屋顶等组件。传统方式可能是这样的:
House house = new House(4, 2, 6, true, "红砖", "木头", "瓷砖");
这种方式有几个问题:
建造者模式将对象的构造过程抽象为独立的步骤,每个步骤都可以被单独调用,最后一次性创建完整的对象。
让我们通过一个图例来理解建造者模式的结构:
┌───────────────┐ uses ┌───────────────┐
│ Client │───────────────▶│ Director │
└───────────────┘ └───────┬───────┘
│
│ uses
▼
┌───────────────┐ builds ┌───────────────┐
│ Product │◀───────────────│ Builder │
└───────────────┘ └───────┬───────┘
│
│ implements
▼
┌───────────────┐
│ConcreteBuilder│
└───────────────┘
这个图解展示了以下组件:
让我们用建造房子作为例子,看看建造者模式如何工作:
创建过程
┌─────────────────────────────────┐
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │ ┌───────────┐
│ │ │ │ │ │ │ │ │ │
│ │墙壁 │───▶│门窗 │───▶│屋顶 │─┼────▶│ 完整房屋 │
│ │ │ │ │ │ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │ └───────────┘
│ │
└─────────────────────────────────┘
下面是一个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 │
│ (可选) │
└─────────────┘
Java中的几个常见例子:
StringBuilder
和 StringBuffer
DocumentBuilder
在Java的XML处理中建造者模式是一种强大的设计模式,尤其适合创建复杂对象。它将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式提高了代码的可读性、可维护性,并且提供了一种创建复杂对象的清晰方式。
当你面对具有许多属性的复杂对象时,考虑使用建造者模式,它可以让你的代码更加整洁和灵活。