問題引出:
Android developer都寫過AlertDialog,用法是先new 一個builder,然后往builder里設置屬性的值,最后調用build得到類實例,完成抽象出來的類的實例化。
一個類的實例化為什么不是簡單的new 對象,為什么要使用這種builder模式去build呢?
難寫、難讀、難維護 的重疊構造器:
Dialog中需要設置必要的參數ignorebutton、positivebutton,和可選的title、content、icon參數,這樣就存在不止一個構造函數,類似
new Dialog(ignorebutton, positivebutton);
new Dialog(title, ignorebutton, positivebutton);
....
code中常有一個類有多個構造函數,構造函數的參數個數一般遞增,層層調用,我們叫他重疊構造器模式(telescoping constructor)。
參數個數少用這個不會有問題,參數個數多了,創建構造函數時,寫參數會讓人頭疼,修改參數會讓人很難維護。
易維護、難一致的JavaBean:
使用JavaBean的方式可以避免傳參數不知道對應哪個字段、修改參數類型容易對應錯的問題。在JavaBean的setter方法中明確了對應的字段和類型。省去了重疊構造方法。
但JavaBean也有他的缺陷, JavaBean對象可以隨時調用setter方法進行設置,這會讓Bean缺乏一致性、也就是類的實例的一致性沒法保證了。特別是在多線程情況下,會出現很難分析的bug。
2 int x,
3 int y,
4 setx(){}
5 setY(){}
6 }
保證了一致性、靈活性的Builder對象:
Builder模式解決了JavaBean一致性的問題, 在Bean中創建內部Builder類,使用Builder中類似setter的方法設置對應的屬性給Builder。然后通過public Bean build(){}方法,實例化Bean對象並返回給客戶調用者,重要的是這個Bean對象是確定下來的, 而且Builder模式的靈活性,可以通過不同的setter生成多個自定義的Bean對象。
class Builder{
int x;
int y;
public void setX( int x) {
this.x = x;
}
public void setY( int y) {
this.y = y;
}
public Bean build(){
return new Builder();
}
}
}
客戶使用Builder模式的方式:
bean和Bean2是2個完全獨立的對象,而且每個單獨的對象一旦創建不會存在變化導致的線程安全問題。