builder模式创建对象:
自定义为对象实际所需字段赋值,避免代码冗余杂乱
备注:2019/10/15 出现映射报错:
解决:需要与数据库数据进行映射时,不用final修饰属性了,同时需要提供public空构造器
使用场景:需要生成的对象具有复杂的内部结构(对象内部结构不复杂不建议使用builder模式)
简单使用案例:
public class User {
private final String firstName; // 必传参数,属性都是不可变final
private final String lastName; // 必传参数
private final int age; // 可选参数
private final String phone; // 可选参数
private User(UserBuilder builder) { //构造方法私有
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
}
//对外只提供getters方法
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
//内部类构造方法只接收必传参数
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// 通过UserBuilder给User的其他非必传参数设值
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
/**
* builder线程不安全
* 所以需要检查参数的合法性时【必须在对象创建完成之后再检查】
* 写法如下:
*/
User user = new User(this); //需要先创建对象
if(user.getAge() > 120){ //然后再对需要检查的参数进行检查
throw new IllegalStateException("年龄超出了范围");
}
return user; //最后将user实例返回出去
}
}
@Override
public String toString() {
return "User{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
", phone='" + phone + '\''+
'}';
}
}
使用:
public class test {
public static void main(String[] args) {
// 很好的避免了:传统的构建多个构造器,不需要字段时传递null字段的情况
// 赋值必填字段后,更具实际所需,为其他字段赋值即可
User user = new User.UserBuilder("王", "小二")
.age(121)
.phone("123456789")
.build();
System.out.println(user);
}
}