开发中经常会遇到构造方法的参数很多,需要确认参数个数和位置;容易出现参数传错位的问题,而且 bug 不好排查。
如果使用默认构造方法,提供 public set 方法,又会把构造对象属性的修改权限放开,导致对象的属性数据安全问题。
这时候,可以使用 Builder 者模式。
package constxiong.interview.design;/** * 对象人 * @author ConstXiong */public class Person { /** * id */ private final int id; /** * 姓名 */ private final String name; /** * 性别 */ private final String sex; /** * 身高 */ private final Double height; /** * 体重 */ private final Double weight; public static class Builder { private int id; private String name; private String sex; private Double height; private Double weight; public Builder() { } public Builder id(int id) { this.id = id; return this; } public Builder name(String name) { this.name = name; return this; } public Builder sex(String sex) { this.sex = sex; return this; } public Builder height(Double height) { this.height = height; return this; } public Builder weight(Double weight) { this.weight = weight; return this; } public Person build() { return new Person(this); } } private Person(Builder builder) { this.id = builder.id; this.name = builder.name; this.sex = builder.sex; this.height = builder.height; this.weight = builder.weight; } }
创建 Person 对象的代码
Person person = new Person.Builder() .id(1) .name("ConstXiong") .sex("男") .height(1.70) .weight(150.0) .build();
Builder 模式需要注意是,Builder 类是静态内部类、类的构造方法是 private 的且参数为 Builder 对象。
Builder 模式不仅可以解决构造过程数据安全、参数过多、可读性的问题,还可以自动填充参数、为生成对象前对参数之间的关系进行合法校验等…
Builder 模式也带了新的问题:
- 创新对象前,必须创建 Builder 对象,多一些性能开销,对性能要求极高的场景下慎用。
- Builder 模式跟 1、2 两种方式比,代码行数更多,显得有点啰嗦。