建造者模式 (Builder Pattern)
模式定义
建造者模式是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
核心要点
- 将对象的构建过程封装在 Builder 中
- 支持链式调用(Fluent API)
- 适用于参数多的对象创建
实现方式
1. 传统建造者模式
java
// 产品类
public class Computer {
private String cpu;
private String ram;
private String storage;
private String gpu;
private String motherboard;
public Computer(String cpu, String ram, String storage, String gpu, String motherboard) {
this.cpu = cpu;
this.ram = ram;
this.storage = storage;
this.gpu = gpu;
this.motherboard = motherboard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", storage='" + storage + '\'' +
", gpu='" + gpu + '\'' +
", motherboard='" + motherboard + '\'' +
'}';
}
}
// 抽象建造者
public abstract class ComputerBuilder {
protected Computer computer;
public void createNewComputer() {
computer = new Computer(null, null, null, null, null);
}
public Computer getComputer() {
return computer;
}
public abstract void buildCpu();
public abstract void buildRam();
public abstract void buildStorage();
public abstract void buildGpu();
public abstract void buildMotherboard();
}
// 具体建造者 - 游戏电脑
public class GamingComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.cpu = "Intel i9-13900K";
}
@Override
public void buildRam() {
computer.ram = "32GB DDR5";
}
@Override
public void buildStorage() {
computer.storage = "2TB NVMe SSD";
}
@Override
public void buildGpu() {
computer.gpu = "NVIDIA RTX 4090";
}
@Override
public void buildMotherboard() {
computer.motherboard = "ASUS ROG Maximus";
}
}
// 具体建造者 - 办公电脑
public class OfficeComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.cpu = "Intel i5-13400";
}
@Override
public void buildRam() {
computer.ram = "16GB DDR4";
}
@Override
public void buildStorage() {
computer.storage = "512GB SSD";
}
@Override
public void buildGpu() {
computer.gpu = "集成显卡";
}
@Override
public void buildMotherboard() {
computer.motherboard = "Intel B660";
}
}
// 指挥者
public class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}
public void setBuilder(ComputerBuilder builder) {
this.builder = builder;
}
public Computer constructComputer() {
builder.createNewComputer();
builder.buildCpu();
builder.buildRam();
builder.buildStorage();
builder.buildGpu();
builder.buildMotherboard();
return builder.getComputer();
}
}
// 测试代码
public class BuilderDemo {
public static void main(String[] args) {
// 构建游戏电脑
ComputerDirector director = new ComputerDirector(new GamingComputerBuilder());
Computer gamingComputer = director.constructComputer();
System.out.println("游戏电脑: " + gamingComputer);
// 构建办公电脑
director.setBuilder(new OfficeComputerBuilder());
Computer officeComputer = director.constructComputer();
System.out.println("办公电脑: " + officeComputer);
}
}2. 内部静态类建造者(推荐)
这是 Java 中最常见的建造者实现方式,Lombok 的 @Builder 也是基于此实现。
java
public class HttpRequest {
private final String url;
private final String method;
private final Map<String, String> headers;
private final String body;
private final int timeout;
// 私有构造函数
private HttpRequest(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers;
this.body = builder.body;
this.timeout = builder.timeout;
}
// 静态内部类 Builder
public static class Builder {
// 必填参数
private final String url;
// 可选参数,设置默认值
private String method = "GET";
private Map<String, String> headers = new HashMap<>();
private String body = "";
private int timeout = 30000;
// 构造函数只接收必填参数
public Builder(String url) {
this.url = url;
}
// 链式调用设置可选参数
public Builder method(String method) {
this.method = method;
return this;
}
public Builder header(String key, String value) {
this.headers.put(key, value);
return this;
}
public Builder headers(Map<String, String> headers) {
this.headers.putAll(headers);
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder timeout(int timeout) {
this.timeout = timeout;
return this;
}
// 构建对象
public HttpRequest build() {
return new HttpRequest(this);
}
}
@Override
public String toString() {
return "HttpRequest{" +
"url='" + url + '\'' +
", method='" + method + '\'' +
", headers=" + headers +
", body='" + body + '\'' +
", timeout=" + timeout +
'}';
}
}
// 使用方式
public class BuilderPatternDemo {
public static void main(String[] args) {
// 最简形式
HttpRequest request1 = new HttpRequest.Builder("https://api.example.com")
.build();
// 完整形式
HttpRequest request2 = new HttpRequest.Builder("https://api.example.com/users")
.method("POST")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer token123")
.body("{\"name\": \"张三\"}")
.timeout(5000)
.build();
System.out.println(request1);
System.out.println(request2);
}
}3. Step Builder(步骤建造者)
当构建过程有明确的步骤顺序时使用。
java
public class NetworkClient {
private final String host;
private final int port;
private final boolean useSsl;
private final int maxRetries;
private final int connectTimeout;
private NetworkClient(StepBuilder builder) {
this.host = builder.host;
this.port = builder.port;
this.useSsl = builder.useSsl;
this.maxRetries = builder.maxRetries;
this.connectTimeout = builder.connectTimeout;
}
// 步骤接口
public interface Step1 {
Step2 host(String host);
}
public interface Step2 {
Step3 port(int port);
}
public interface Step4 {
Step4 useSsl(boolean useSsl);
Step4 maxRetries(int retries);
Step4 connectTimeout(int timeout);
NetworkClient build();
}
public static class StepBuilder implements Step1, Step2, Step4 {
private String host;
private int port;
private boolean useSsl = false;
private int maxRetries = 3;
private int connectTimeout = 5000;
private StepBuilder() {}
public static Step1 create() {
return new StepBuilder();
}
@Override
public Step2 host(String host) {
this.host = host;
return this;
}
@Override
public Step3 port(int port) {
this.port = port;
return new Step3(this);
}
@Override
public Step4 useSsl(boolean useSsl) {
this.useSsl = useSsl;
return this;
}
@Override
public Step4 maxRetries(int retries) {
this.maxRetries = retries;
return this;
}
@Override
public Step4 connectTimeout(int timeout) {
this.connectTimeout = timeout;
return this;
}
@Override
public NetworkClient build() {
if (host == null || host.isEmpty()) {
throw new IllegalStateException("host is required");
}
if (port <= 0) {
throw new IllegalStateException("port must be positive");
}
return new NetworkClient(this);
}
}
// Step3 作为可选步骤的入口
public static class Step3 implements Step4 {
private final StepBuilder builder;
Step3(StepBuilder builder) {
this.builder = builder;
}
@Override
public Step4 useSsl(boolean useSsl) {
builder.useSsl = useSsl;
return this;
}
@Override
public Step4 maxRetries(int retries) {
builder.maxRetries = retries;
return this;
}
@Override
public Step4 connectTimeout(int timeout) {
builder.connectTimeout = timeout;
return this;
}
@Override
public NetworkClient build() {
return builder.build();
}
}
@Override
public String toString() {
return "NetworkClient{" +
"host='" + host + '\'' +
", port=" + port +
", useSsl=" + useSsl +
", maxRetries=" + maxRetries +
", connectTimeout=" + connectTimeout +
'}';
}
}
// 使用
// NetworkClient client = StepBuilder.create()
// .host("example.com") // 必须
// .port(443) // 必须
// .useSsl(true) // 可选
// .maxRetries(5) // 可选
// .build();JDK 中的建造者模式
StringBuilder
java
String result = new StringBuilder()
.append("Hello")
.append(" ")
.append("World")
.toString();Stream.Builder
java
Stream<String> stream = Stream.<String>builder()
.add("Java")
.add("设计模式")
.add("建造者")
.build();Locale.Builder
java
Locale locale = new Locale.Builder()
.setLanguage("zh")
.setRegion("CN")
.build();与 Lombok @Builder
java
@Builder
@Data
public class User {
private String name;
private int age;
private String email;
private String phone;
}
// Lombok 自动生成的使用方式
User user = User.builder()
.name("张三")
.age(25)
.email("zhangsan@example.com")
.build();优缺点
优点:
- 封装性好,客户端不需要知道产品内部细节
- 链式调用,代码可读性高
- 可以精细控制构建过程
- 支持不可变对象的创建
缺点:
- 会产生额外的 Builder 类,增加代码量
- 如果产品内部结构复杂,建造者也会很复杂
适用场景
- 对象有很多可选参数
- 需要创建不同的表示
- 构建过程需要多步骤
- 需要不可变对象