简介

当类的构造器参数较多(尤其是包含大量可选参数)时,使用 Builder 模式 能更优雅。

三种模式创建多参数对象

重叠构造器模式

设要创建一个 User 类,包含以下参数:
id(必填)、username(必填)、age(可选)、email(可选)、phone(可选)。

举个例子 🌰

public class User {
    private final int id;
    private final String username;
    private final int age;
    private final String email;
    private final String phone;

    // 多个构造器导致代码冗余
    public User(int id, String username) {
        this(id, username, 0);
    }

    public User(int id, String username, int age) {
        this(id, username, age, null);
    }

    public User(int id, String username, int age, String email) {
        this(id, username, age, email, null);
    }

    public User(int id, String username, int age, String email, String phone) {
        this.id = id;
        this.username = username;
        this.age = age;
        this.email = email;
        this.phone = phone;
    }
}

重叠构造器模式的缺点❌

重叠构造器方式需要编写多个重载构造器,导致代码臃肿且难以维护。

JavaBean 模式

JavaBean模式(即无参构造器加setter方法)的特点是:提供无参构造器,通过 setter 方法设置属性。

举个例子 🌰

public class User {
    private int id;
    private String username;
    private int age;
    private String email;
    private String phone;

    // 无参构造器(强制存在)
    public User() {}

    // 通过 setter 方法设置属性
    public void setId(int id) { this.id = id; }
    public void setUsername(String username) { this.username = username; }
    public void setAge(int age) { this.age = age; }
    public void setEmail(String email) { this.email = email; }
    public void setPhone(String phone) { this.phone = phone; }
}

使用 JavaBean 创建对象

User user = new User();
user.setId(007);
user.setUsername("Zhangsan");
user.setAge(25);
user.setEmail("zhangsan@gmail.com");
user.setPhone("123456789");

JavaBean 模式的缺点的缺点❌

1.需要多次调用 setter,代码冗长。
2.对象状态可能不一致:在调用所有 setter 方法之前,对象处于“未完全初始化”状态
3.无法实现不可变对象:JavaBean 依赖 setter 修改属性,导致对象状态可变,多线程环境下可能引发竞态条件。比如:一个线程正在设置 user.setAge(25),另一个线程可能同时调用 user.setAge(30),导致最终结果不确定。

Builder 模式

使用 Builder 模式 优雅地处理多参数构造问题。

举个例子 🌰

public class User {
    private final int id;
    private final String username;
    private final int age;
    private final String email;
    private final String phone;

    // 私有构造器,只能通过 Builder 创建实例
    private User(Builder builder) {
        this.id = builder.id;
        this.username = builder.username;
        this.age = builder.age;
        this.email = builder.email;
        this.phone = builder.phone;
    }

    // 静态内部 Builder 类
    public static class Builder {
        // 必填参数
        private final int id;
        private final String username;

        // 可选参数(设置默认值)
        private int age = 0;
        private String email = null;
        private String phone = null;

        // 必填参数通过 Builder 构造器传入
        public Builder(int id, String username) {
            this.id = id;
            this.username = username;
        }

        // 为每个可选参数提供链式方法
        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder email(String email) {
            this.email = email;
            return this;
        }

        public Builder phone(String phone) {
            this.phone = phone;
            return this;
        }

        // 最终构建 User 对象
        public User build() {
            return new User(this);
        }
    }
}

使用 Builder 链式调用创建对象

User user = new User.Builder(1, "Zhangsan")
    .age(25)
    .email("zhangsan@gmail.com")
    .phone("123456789")
    .build();

Builder 模式的优点✅

1.灵活处理可选参数:不需要为每个参数组合编写多个构造器。
2.保证对象一致性:在 build() 方法中可添加参数校验逻辑,确保对象有效性。
3.线程安全:Builder 实例仅在当前线程使用,最终通过 build() 生成不可变对象。

总结

在需要处理多参数、必填参数、不可变对象或线程安全的场景下,Builder 模式 明显优于重叠构造器模式和 JavaBean 模式。


我爱吃炒煤
1 声望0 粉丝