假如我们的一个实体类有很多的属性值,但是这些属性值又是可选的。如果我们遇到这样的是类,如何设计出方便的实体类呢?
通常解决办法一: 重叠构造器
public classUser {private String id; //id(必填)
private String name; //用户名(必填)
private String email; //邮箱(可选)
private int age; //年龄(可选)
private String phoneNumber; //电话(可选)
private String address; //地址(可选)
publicUser(String id, String name) {this(id, name, "qq.com", 0, "120", "广州");
}publicUser(String id, String name, String email) {this(id, name, email, 0, "120", "广州");
}public User(String id, String name, String email, intage) {this(id, name, email, age, "120", "广州");
}public User(String id, String name, String email, intage, String phoneNumber) {this(id, name, email, age, phoneNumber, "广州");
}public User(String id, String name, String email, intage, String phoneNumber, String address) {this.id =id;this.name =name;this.email =email;this.age =age;this.phoneNumber =phoneNumber;this.address =address;
}publicString getId() {returnid;
}publicString getName() {returnname;
}publicString getEmail() {returnemail;
}public intgetAge() {returnage;
}publicString getPhoneNumber() {returnphoneNumber;
}publicString getAddress() {returnaddress;
}
}
注:许多你不想设置的参数,但是还不得不为他们传递值
通常解决办法一: JavaBean模式(调用一个无参构造器来创造对象,然后调用setter方法来设置每个必须的参数,以及每个相关的可选参数)
public classUser {private String id; //id(必填)
private String name; //用户名(必填)
private String email; //邮箱(可选)
private int age; //年龄(可选)
private String phoneNumber; //电话(可选)
private String address; //地址(可选)publicUser() {super();
}public voidsetId(String id) {this.id =id;
}public voidsetName(String name) {this.name =name;
}public voidsetEmail(String email) {this.email =email;
}public void setAge(intage) {this.age =age;
}public voidsetPhoneNumber(String phoneNumber) {this.phoneNumber =phoneNumber;
}public voidsetAddress(String address) {this.address =address;
}publicString getId() {returnid;
}publicString getName() {returnname;
}publicString getEmail() {returnemail;
}public intgetAge() {returnage;
}publicString getPhoneNumber() {returnphoneNumber;
}publicString getAddress() {returnaddress;
}
@OverridepublicString toString() {return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + ", phoneNumber="
+ phoneNumber + ", address=" + address + "]";
}
}
注:JavaBeans模式自身有着很严重的缺点。因为构造过程被分到几个调用中,在构造过程中JavaBean可能处于非一致的状态。JavaBeans模式阻止了把类做成不可变的可能,这就需要确保他的线程安全。
解决办法三: 构建器
public classUser {private String id; //id(必填)
private String name; //用户名(必填)
private String email; //邮箱(可选)
private int age; //年龄(可选)
private String phoneNumber; //电话(可选)
private String address; //地址(可选)
public static classBuilder{private String id; //id(必填)
private String name; //用户名(必填)
private String email; //邮箱(可选)
private int age; //年龄(可选)
private String phoneNumber; //电话(可选)
private String address; //地址(可选)
publicBuilder(String id, String name) {super();this.id =id;this.name =name;
}publicBuilder email(String email){this.email =email;return this;
}public Builder age(intage){this.age =age;return this;
}publicBuilder phoneNumber(String phoneNumber){this.phoneNumber =phoneNumber;return this;
}publicBuilder address(String address){this.address =address;return this;
}publicUser builder(){return new User(this);
}
}privateUser(Builder builder){this.id =builder.id;this.name =builder.name;this.email =builder.email;this.age =builder.age;this.phoneNumber =builder.phoneNumber;this.address =builder.address;
}
@OverridepublicString toString() {return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + ", phoneNumber="
+ phoneNumber + ", address=" + address + "]";
}publicString getId() {returnid;
}publicString getName() {returnname;
}publicString getEmail() {returnemail;
}public intgetAge() {returnage;
}publicString getPhoneNumber() {returnphoneNumber;
}publicString getAddress() {returnaddress;
}
}
注:不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。
测试代码
public static voidmain( String[] args )
{
User user= new User.Builder(UUID.randomUUID().toString(), "parry").address("广州").builder();
System.out.println(user.toString());
}