遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮用構(gòu)建器
靜態(tài)工廠和構(gòu)造器有個(gè)共同的局限性:它們都不能很好的擴(kuò)展到大量的可選參數(shù)
當(dāng)遇到大量的可選參數(shù)時(shí)候侣灶,一般的處理方式是重載構(gòu)造方法
重載構(gòu)造器模式可行魁袜,但是當(dāng)有許多參數(shù)的時(shí)候,客戶端代碼很難編寫靡馁,并且難以閱讀
一長串類型相同的參數(shù)會(huì)導(dǎo)致一些微妙的錯(cuò)誤,如果客戶端不小心顛倒了其中兩個(gè)參數(shù)的順序,編譯器也不會(huì)出錯(cuò)簇搅,但是程序在運(yùn)行的時(shí)候回出現(xiàn)一些錯(cuò)誤的行為
- 替代方式一
即JavaBean模式,在這種模式下調(diào)用一個(gè)誤餐構(gòu)造器來創(chuàng)建對(duì)象软吐,然后調(diào)用setter方法來設(shè)置每個(gè)必要的參數(shù)瘩将,以及每個(gè)相關(guān)的可選參數(shù)
Person mPerson = new Person();
mPerson.setName("bob");
mPerson.setAge(10);
mPerson.setProfession("doctor")
...
遺憾的是javaBean模式自身有著很嚴(yán)重的缺點(diǎn),因?yàn)闃?gòu)造過程被分割到好多個(gè)set中容易造成線程不安全凹耙,導(dǎo)致對(duì)象處于不一致的狀態(tài)
- 替代方式二
既能保證像重疊模式那樣的安全姿现,也能保證像javaBeans模式那么好的可讀性,這就是builder模式的一種形式
public class NutritionFacts {
private int servingSize ;
private int servings ;
private int calories;
private int fat ;
private int sodium ;
private int carbohydrate;
public static class Builder {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate;
public Builder(int servingSize, int servings) {
this.servings = servings;
this.servingSize = servingSize;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder carbohydreate(int val){
carbohydrate = val;
return this;
}
public Builder sodium(int val){
sodium = val;
return this;
}
public Builder fat(int val){
fat = val;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium =builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
所有的默認(rèn)參數(shù)值都單獨(dú)放在一個(gè)地方肖抱,builder的setter方法返回其本身备典,這樣就可以把調(diào)用連接起來,客戶端代碼如下:
NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).
calories(100).sodium(35).build();
這樣的客戶端代碼很同意編寫意述,跟為重要的是提佣,易于閱讀,builder模式模擬了具體名字的可選參數(shù)
builder像個(gè)構(gòu)造器一樣荤崇,可以對(duì)其參數(shù)強(qiáng)加約束條件拌屏,builder方法可以檢驗(yàn)這些約束條件,將參數(shù)從builder拷貝到對(duì)象中之后术荤,并在對(duì)象域而不是builder域中對(duì)他們進(jìn)行檢驗(yàn)倚喂,如果違反了任何約束條件,builder方法就應(yīng)該拋出ILLegalStateException瓣戚,異常的詳細(xì)信息應(yīng)該顯示出違反了那個(gè)約束條件