小易说IT 小易说IT

Java 建造者Builder 模式代码示例

建造者模式:用于构建复杂对象,把对象的构造和表示分离,支持链式调用,适合属性多、部分属性可选的实体。 两种常见写法:

  1. 传统独立 Builder 类(GoF 标准建造者)

  2. 静态内部类 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 模式要点总结

  1. 静态内部类 Builder:业务开发 95% 场景,链式调用,对象可以设计为不可变对象(成员变量 final)

  2. GOF 抽象建造者 + Director:需要多种不同产品、组装流程固定时才使用

  3. 优点:

    • 避免多参数构造器重载爆炸;

    • 链式调用可读性好;

    • build () 方法统一参数校验;

  4. 缺点:代码量增加(Lombok 解决模板代码)


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://yijunzhao.cc/archives/java-builder-pattern-code-examples

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/