想必受过 POJO 中 getter、setter、toString 方法折磨的同学都用过 Lombok,今天我们就一起来探讨一下 Lombok 中是怎样实现 Builder 模式的。
User 类
假设我们存在这样一个 POJO 类,而且客户端在构建 User 对象时并非所有的字段都是必选的。
1 2 3 4 5 6 7
| public class User { private String name; private int age; private String phone; private Address address; }
|
1 2 3 4
| public class Address { private String zip; private String name; }
|
不用 Builder 模式
为了满足上述场景,我们需要为 User 类构建如下所示的构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public User(String name) { this(name, 0); }
public User(String name, int age) { this(name, age, null); }
public User(String name, int age, String phone) { this(name, age, phone, null); }
public User(String name, int age, String phone, Address address) { this.name = name; this.age = age; this.phone = phone; this.address = address; }
|
不但有着繁杂的构造函数,而且客户端调用时还需要注意传参的顺序。
使用 Builder 模式
通过 Lombok 中 @Builder 注解生成的 User 类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class User { private String name; private int age; private String phone; private Address address;
//User 类只需要一个接收全部参数的构造函数即可,剩下的工作交给 UserBuilder 类。 User(String var1, int var2, String var3, Address var4) { this.name = var1; this.age = var2; this.phone = var3; this.address = var4; } //这里之所以将方法定义为 static,是为了方便客户端通过 User.builder() 的调用形式来生成 UserBuilder 对象。 public static User.UserBuilder builder() { return new User.UserBuilder(); }
public static class UserBuilder { private String name; private int age; private String phone; private Address address;
UserBuilder() { } //通过链式调用避免了 User 中繁杂的构造函数 public User.UserBuilder name(String var1) { this.name = var1; return this; } public User.UserBuilder age(int var1) { this.age = var1; return this; } public User.UserBuilder phone(String var1) { this.phone = var1; return this; } public User.UserBuilder address(Address var1) { this.address = var1; return this; } //最后通过 build 方法构建出指定的 User 对象,然后返回给客户端。 public User build() { return new User(this.name, this.age, this.phone, this.address); } public String toString() { return "User.UserBuilder(name=" + this.name + ", age=" + this.age + ", phone=" + this.phone + ", address=" + this.address + ")"; } } }
|
而客户端只需要一行代码就可以生成任意入参的 User 对象,十分方便。
1
| User user = User.builder().name("小明").age(13).build();
|
总结
- Builder 模式可以避免繁杂的构造函数。
- Builder 模式可以简洁客户端的代码。
代码
github 地址
引用