【设计模式系列】建造者模式(十)
目录
一、什么是建造者模式
二、建造者模式的角色
三、建造者模式的典型应用
四、建造者模式在StringBuilder中的应用
五、典型建造者模式的案例
一、什么是建造者模式
建造者模式(Builder Pattern)是一种创建型设计模式,用于构建复杂对象。它将一个复杂对象的构建和表示分离,使得同样的构建过程可以创建不同的表示。
二、建造者模式的角色
-
Product(产品角色):Product是最终要构建的复杂对象的类。它定义了产品的属性和行为,但不包含构建逻辑。
-
Builder(抽象建造者):Builder是一个接口或抽象类,它声明了用于构建Product对象的各个步骤的方法。这些方法通常返回Builder对象本身,以支持链式调用。其中Builder类不实现具体的构建逻辑,而是在具体的建造者类中实现。
-
ConcreteBuilder(具体建造者):ConcreteBuilder实现了Builder接口,并提供了构建Product对象的具体逻辑。它负责创建Product的实例,并根据Builder接口中定义的方法来组装产品。
-
Director(指挥者)(可选):Director类负责管理构建过程,它接受一个Builder对象,并使用该对象的构建方法来创建一个Product对象。Director类使得构建过程与客户端代码解耦。
三、建造者模式的典型应用
-
复杂对象的构建: 建造者模式允许逐步构建复杂对象,特别适用于创建具有许多配置选项的对象。例如,在Java核心库中,
StringBuilder
和StringBuffer
的append()
方法就是建造者模式的典型应用,它们允许动态地构建字符串。 -
不同表现形式的产品构建: 当需要创建不同表现形式的产品时,可以使用建造者模式。例如,可以同时构建纸质和电子版手册,尽管这两种产品不遵循相同的接口,但可以使用相同的构建步骤。
四、建造者模式在StringBuilder中的应用
在Java中,StringBuilder
类并没有直接使用建造者模式,但我们可以类比理解。StringBuilder
提供了一种可变的字符序列,它允许我们通过链式调用来构建字符串。虽然StringBuilder
不是通过建造者模式构建的,但它提供了一种类似建造者模式的接口风格,允许我们逐步构建字符串。
如果我们想要模拟建造者模式在StringBuilder
中的应用,可以创建一个StringBuilderBuilder
类,它包含一个StringBuilder
对象,并提供一系列方法来构建字符串,如下所示:
public class StringBuilderBuilder {
private StringBuilder stringBuilder;
public StringBuilderBuilder() {
this.stringBuilder = new StringBuilder();
}
public StringBuilderBuilder append(String str) {
this.stringBuilder.append(str);
return this; // 返回自身以支持链式调用
}
public StringBuilderBuilder append(int value) {
this.stringBuilder.append(value);
return this;
}
public StringBuilderBuilder append(char value) {
this.stringBuilder.append(value);
return this;
}
// 更多的append方法...
public String build() {
return this.stringBuilder.toString();
}
}
// 使用
StringBuilderBuilder builder = new StringBuilderBuilder();
String result = builder.append("Hello").append(" ").append("World").build();
在这个例子中,StringBuilderBuilder
类扮演了建造者的角色,它提供了一系列的append
方法来逐步构建字符串,并最终通过build
方法返回构建好的字符串。这种方式使得字符串的构建过程更加清晰和灵活。
五、典型建造者模式的案例
1. 定义产品类(Product)
public class Computer {
private String cpu;
private String memory;
private String hardDisk;
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
this.hardDisk = builder.hardDisk;
}
public void assemble() {
System.out.println("Assembling computer with CPU: " + cpu + ", Memory: " + memory + ", Hard Disk: " + hardDisk);
}
public static class Builder {
private String cpu;
private String memory;
private String hardDisk;
public Builder setCPU(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMemory(String memory) {
this.memory = memory;
return this;
}
public Builder setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
2. 定义指挥者类(Director)
public class ComputerDirector {
private Computer.Builder builder;
public ComputerDirector(Computer.Builder builder) {
this.builder = builder;
}
public Computer construct() {
builder.setCPU("Intel i7");
builder.setMemory("16GB");
builder.setHardDisk("1TB");
return builder.build();
}
}
3. 使用建造者模式和指挥者构建对象
public class Client {
public static void main(String[] args) {
// 创建具体的建造者对象
Computer.Builder builder = new Computer.Builder();
// 创建指挥者对象,并传入建造者对象
ComputerDirector director = new ComputerDirector(builder);
// 使用指挥者对象指导构建过程
Computer computer = director.construct();
// 组装电脑
computer.assemble();
}
}
- Computer:产品类,包含三个属性:CPU、内存和硬盘。构造函数是私有的,只能通过内部的
Builder
类来创建对象。 - Builder:
Computer
的内部静态类,实现了建造者模式。提供了setCPU
、setMemory
和setHardDisk
方法来设置Computer
的属性,并返回Builder
对象本身以支持链式调用。build
方法用于创建Computer
对象。 - ComputerDirector:指挥者类,它接受一个
Computer.Builder
对象,并使用该对象的构建方法来创建一个Computer
对象。construct
方法定义了构建Computer
对象的步骤。 - Client:客户端代码创建
Computer.Builder
对象,然后创建ComputerDirector
对象并传入Builder
对象。客户端使用ComputerDirector
的construct
方法来指导构建过程,并最终组装电脑。