假设有一个用有多个属性的java bean,想在得到这个bean的时候,就已经将其属性初始化好
public class Persion {
private int age;
private String name;
private String email;
private String phone;
}
如果追求不可变性,实际应该让它只有getter方法,然后在构造函数里把属性初始化完成.然而下面这个构造函数有个问题,用户使用的时候,不看文档,很难知道后面3个字符串都是什么
public Persion(int age, String name, String email, String phone) {
this.age = age;
this.name = name;
this.email = email;
this.phone = phone;
}
构造这个java bean也可以使用常规的方法,即使用一个无参的构造函数
Persion persion = new Persion();
persion.setName("name");
persion.setEmail("email");
persion.setAge(10);
persion.setPhone("phone");
这段代码的问题在哪里呢?在于输入太多!真正在IDE中敲一次会发现,每次都需要用键盘敲打"persion",然后才能按"."让IDE提示方法.这样会破坏编写代码的流畅性,没有连续按"."出现方法的快感.
有可能有同学提出一个解决方案,那就是让setter方法最后return this
public Persion setAge(int age) {
this.age = age;
return this;
}
在使用时
persion.setName("name").setEmail("email"),setAge(10).setPhone("phone");
这样倒是可以链式调用,但是这个方案的问题在于破坏了单一职责原则,setAge方法既有副作用(改变了age变量,修改了对象的内部状态),又有返回值,实际上不是一个优雅的实现.
既要有流畅的编程体验,又要优美的代码,这时就需要builder模式了,典型的代码实现
public class Person {
private int age;
private String name;
private String email;
private String phone;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
private Person(int age, String name, String email, String phone) {
this.age = age;
this.name = name;
this.email = email;
this.phone = phone;
}
public static PersonBuilder builder() {
return new PersonBuilder();
}
public static class PersonBuilder {
private int age;
private String name;
private String email;
private String phone;
public PersonBuilder age(int age) {
this.age = age;
return this;
}
public PersonBuilder name(String name) {
this.name = name;
return this;
}
public PersonBuilder email(String email) {
this.email = email;
return this;
}
public PersonBuilder phone(String phone) {
this.phone = phone;
return this;
}
public Person build() {
return new Person(age, name, email, phone);
}
}
}
使用时代码如下
Person persion = Person.builder()
.age(10)
.name("name")
.email("email")
.phone("phone")
.build();
这样代码看起来漂亮很多
现在的builder是可变builder,因为每个方法都改变了自身的状态,并且return了this.我们也可以使用非可变的builder
例如
public PersonBuilder phone(String phone) {
return new PersonBuilder(this.age, this.name, this.email, phone);
}
这样有什么好处呢,是可以提供一个基础的builder,让使用者按需定制而不会互相影响,例如
PersonBuilder baseBuilder = Person.builder().age(10);
Person bar = baseBuilder.email("bar").build();
Person foo = baseBuilder.email("foo").build();
网友评论