首先想到的,毫无疑问是重叠构造器,需要啥域成员可变的时候可以自行构造。但是,这种模式存在很大的问题,那就是假如域成员很多,构造函数需要定制的参数多变,就会使代码可读性下降。
public class People {
private String name;
private Integer age;
private String phone;
private String address;
private String idNumber;
public People(String name) {
this(name, 0);
}
public People(String name, Integer age) {
this(name, age, "");
}
public People(String name, Integer age, String phone) {
this(name, age, phone, "");
}
public People(String name, Integer age, String phone, String idNumber) {
this(name, age, phone, idNumber, "");
}
public People(String name, Integer age, String phone, String address, String idNumber) {
this.name = name;
this.age = age;
this.phone = phone;
this.address = address;
this.idNumber = idNumber;
}
}
当然,还有第二种方法,很常规的,直接就是使用setXXX()的方式去赋值。但是,这种方法,也有缺陷,这也是JavaBean的缺陷之处。因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。并且,JavaBeans模式使得把类做成不可变的可能性不复存在,要花费额外的力气去保证它的线程安全。
public class People {
private String name;
private Integer age;
private String phone;
private String address;
private String idNumber;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setAddress(String address) {
this.address = address;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public static void main(String[] args) {
People people = new People();
people.setName("xiao ming");
people.setAge(18);
people.setPhone("10000");
people.setAddress("china");
people.setIdNumber("xxx");
}
}
最后一种,是建造者模式的使用。相信很多人都见过这种方法的调用。
new XXX.Builder().setXXX().setXXX().setXXX().build();
这种方法就是很典型的建造者模式的应用之一。这样的设计使得客户端代码很容易编写,更重要的是易于阅读。
public class People{
private final String name;
private final String phone;
private final Integer age;
private final String address;
private final String email;
public People(Builder builder) {
this.name = builder.name;
this.phone = builder.phone;
this.age = builder.age;
this.address = builder.address;
this.email = builder.email;
}
static class Builder {
private String name;
private String phone = "";
private Integer age = 0;
private String address = "";
private String email = "";
public Builder(String name) {
this.name = name;
}
public Builder setPhone(String val) {
phone = val;
return this;
}
public Builder setAge(Integer val) {
age = val;
return this;
}
public Builder setAddress(String val) {
address = val;
return this;
}
public Builder setEmail(String val) {
email = val;
return this;
}
public People build() {
return new People(this);
}
}
public static void main(String[] args) {
Peopletest = new People.Builder("xiaoming")
.setAge(18)
.setAddress("china")
.setPhone("10011")
.setEmail("50011").build();
System.out.println(test.name);
}
}
总结,当类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式是一种不错的选择,比重叠构造器更易于阅读和编写,比JavaBeans更安全。
参考:《Effective java》