在實(shí)例化一個類的過程中萌丈,通常會遇到多個參數(shù)的構(gòu)造函數(shù),但如果有些參數(shù)是非必需的呢揍很?每次都要初始化那么多參數(shù)么郎楼?
public class Person {
private int id;//身份證號
private String name;//姓名
private int age;//年齡
private boolean sex;//性別
private String desc;//個人描述
public Person(int id, String name, int age, boolean sex, String desc) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.desc = desc;
}
}
或者像下面這樣,創(chuàng)建一個必選參數(shù)的構(gòu)造器窒悔,在創(chuàng)建幾個可選參數(shù)的構(gòu)造器呜袁?
public Person(int id, String name) {//兩個參數(shù)的
this.id = id;
this.name = name;
}
public Person(int id, String name, int age) {//三個參數(shù)的
this.id = id;
this.name = name;
this.age = age;
}
public Person(int id, String name, int age, boolean sex) {//四個參數(shù)的
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
或setter方法?
JavaBean模式自身有嚴(yán)重的缺點(diǎn)简珠,因?yàn)闃?gòu)造過程被分到幾個調(diào)用中阶界,在構(gòu)造過程中Javabean可能處于不一致的狀態(tài),類無法僅僅通過檢驗(yàn)構(gòu)造器參數(shù)的有效性來保證一致性。JavaBean模式阻止了把類做成不可變的可能膘融,這就需要程序員付出額外的努力確保線程安全 ---
摘自Effective Java
那么我們該怎樣用構(gòu)建器來實(shí)現(xiàn)類的實(shí)例化而又不受制于構(gòu)造函數(shù)限制呢芜抒?
public class Person {
private final int id;//身份證號
private final String name;//姓名
private int age;//年齡
private boolean sex;//性別
private String desc;//個人描述
private Person(Builder builder){
this.id=builder.id;
this.name=builder.name;
this.age=builder.age;
this.sex=builder.sex;
this.desc=builder.desc;
}
public static class Builder{
private final int id;
private final String name;
private int age;
private boolean sex;
private String desc;
public Builder(int id, String name) {
this.id = id;
this.name = name;
}
public Builder age(int age){
//年齡合法性檢查
if(age<0)throw new IllegalArgumentException();
else this.age=age;
return this;
}
public Builder sex(boolean sex){
this.sex=sex;
return this;
}
public Builder desc(String desc){
this.desc=desc;
return this;
}
public Person build(){
return new Person(this);
}
}
@Override
public String toString() {
return "id:"+this.id+" 姓名:"+this.name+" 年齡:"+this.age+" 性別:"+this.sex+" 描述:"+this.desc;
}
}
我們在main函數(shù)中測試一下
public static void main(String[] args) {
Builder builder=new Person.Builder(123,"張三");
Person person=builder.age(18).sex(false).desc("好好學(xué)習(xí),天天向上").build();
System.out.println(person.toString());
}
用構(gòu)建器創(chuàng)建的實(shí)例易于閱讀和編寫托启,較javaBean模式又更加安全,自然攘宙,自然屯耸,每種方法都會有其優(yōu)點(diǎn)和弊端,選擇合適的使用場景蹭劈,會讓代碼更加健壯易讀疗绣。