建造者模式:用于构建复杂对象,把对象的构造和表示分离,支持链式调用,适合属性多、部分属性可选的实体。 两种常见写法:
传统独立 Builder 类(GoF 标准建造者)
静态内部类 Builder(日常开发最常用,SpringBoot、Lombok@Builder 底层思想)
方式 1:静态内部类 Builder(项目最常用)
/**
* 用户实体,多属性,部分字段可选,使用内部Builder
*/
public class User {
// 必填
private final Long id;
private final String username;
// 可选字段
private String password;
private String email;
private Integer age;
private String address;
// 私有构造器,只能通过Builder构建对象
private User(Builder builder) {
this.id = builder.id;
this.username = builder.username;
this.password = builder.password;
this.email = builder.email;
this.age = builder.age;
this.address = builder.address;
}
// 静态建造者
public static class Builder {
// 必填参数放这里
private final Long id;
private final String username;
// 可选参数,默认值
private String password;
private String email;
private Integer age;
private String address;
// 构造方法接收【必填参数】
public Builder(Long id, String username) {
this.id = id;
this.username = username;
}
// 链式set方法,返回this
public Builder password(String password) {
this.password = password;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder age(Integer age) {
this.age = age;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
// 执行构建,返回目标对象,可以在这里做参数校验
public User build() {
// 可以在这里做参数校验,必填项校验
if (username == null || username.isBlank()) {
throw new IllegalArgumentException("用户名不能为空");
}
return new User(this);
}
}
// getter,没有setter,对象不可变(final)
public Long getId() { return id; }
public String getUsername() { return username; }
public String getPassword() { return password; }
public String getEmail() { return email; }
public Integer getAge() { return age; }
public String getAddress() { return address; }
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
使用示例
public class TestBuilder {
public static void main(String[] args) {
// 链式构建对象,可选字段按需设置
User user = new User.Builder(1001L, "zhangsan")
.password("123456")
.age(28)
.email("zhangsan@test.com")
.address("南京市江宁区")
.build();
System.out.println(user);
// 只传必填,可选全部不传
User simpleUser = new User.Builder(1002L, "lisi")
.build();
System.out.println(simpleUser);
}
}
方式 2:GOF 经典建造者模式(分离抽象建造者、具体建造者、指挥者)
适合产品有多种不同实现,复杂对象多套构建流程
// 产品:电脑
class Computer {
private String cpu;
private String memory;
private String disk;
private String system;
public void setCpu(String cpu) { this.cpu = cpu; }
public void setMemory(String memory) { this.memory = memory; }
public void setDisk(String disk) { this.disk = disk; }
public void setSystem(String system) { this.system = system; }
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", disk='" + disk + '\'' +
", system='" + system + '\'' +
'}';
}
}
// 抽象建造者
abstract class ComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildCpu();
public abstract void buildMemory();
public abstract void buildDisk();
public abstract void buildSystem();
public Computer getResult() {
return computer;
}
}
// 具体建造者:游戏本
class GameBookBuilder extends ComputerBuilder{
@Override
public void buildCpu() { computer.setCpu("i9‑14900HX"); }
@Override
public void buildMemory() { computer.setMemory("32G"); }
@Override
public void buildDisk() { computer.setDisk("2T SSD"); }
@Override
public void buildSystem() { computer.setSystem("Windows11"); }
}
// 具体建造者:办公本
class OfficeBookBuilder extends ComputerBuilder{
@Override
public void buildCpu() { computer.setCpu("i5‑1340P"); }
@Override
public void buildMemory() { computer.setMemory("16G"); }
@Override
public void buildDisk() { computer.setDisk("512G SSD"); }
@Override
public void buildSystem() { computer.setSystem("Windows11"); }
}
// 指挥者Director:统一组装流程,隔离客户端与构建步骤
class Director {
public Computer construct(ComputerBuilder builder){
builder.buildCpu();
builder.buildMemory();
builder.buildDisk();
builder.buildSystem();
return builder.getResult();
}
}
// 测试
public class GofBuilderDemo {
public static void main(String[] args) {
Director director = new Director();
// 构建游戏本
Computer gamePc = director.construct(new GameBookBuilder());
System.out.println(gamePc);
// 构建办公本
Computer officePc = director.construct(new OfficeBookBuilder());
System.out.println(officePc);
}
}
Lombok 简化写法(实际项目)
开发中不会手写大量 Builder 模板,使用
@Builder注解自动生成内部 Builder
<!-- maven依赖 lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
import lombok.Builder;
import lombok.ToString;
@Builder
@ToString
public class UserLombok {
private Long id;
private String username;
private String password;
private String email;
private Integer age;
}
调用:
UserLombok user = UserLombok.builder()
.id(1003L)
.username("wangwu")
.age(22)
.build();
System.out.println(user);
Builder 模式要点总结
静态内部类 Builder:业务开发 95% 场景,链式调用,对象可以设计为不可变对象(成员变量 final)
GOF 抽象建造者 + Director:需要多种不同产品、组装流程固定时才使用
优点:
避免多参数构造器重载爆炸;
链式调用可读性好;
build () 方法统一参数校验;
缺点:代码量增加(Lombok 解决模板代码)
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问