什么是Builder模式
相信很多Android開發(fā)者都使用過形如下面的代碼創(chuàng)建過dialog瓶佳。
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Title")
.setMessage("message")
.setCancelable(true);
AlertDialog dialog = builder.create();
可以看到一個dialog對象并不是通過new關(guān)鍵字傳參來直接創(chuàng)建,而是通過一個中間變量builder來實現(xiàn)旦袋,通過不斷的對builder設(shè)置參數(shù),最后通過builder的一個方法來完成對對象的創(chuàng)建它改。這就是所謂的builder模式疤孕。
Builder模式的實現(xiàn)思路
因為不能通過new來創(chuàng)建,所以構(gòu)造函數(shù)肯定是私有的央拖,而builder類又要調(diào)用構(gòu)造函數(shù)祭阀,所以builder類一定是要創(chuàng)建的主類的內(nèi)部類鹉戚。除此之外,由于是builder對象返回的主類對象专控,所以builder對象肯定持有一個主類的實例對象抹凳。之后便是各種set方法來對這個對象賦值,最后通過一個公共的方法返回該對象伦腐。
單例的實現(xiàn)方式
public class Product {
private String attribute1;
private String attribute2;
private String attribute3;
private Product() {
}
@Override
public String toString() {
return attribute1 + " " + attribute2 + " " + attribute3;
}
public static class Builder {
private Product product = new Product();
public void setAttribute1(String attribute1) {
product.attribute1 = attribute1;
}
public void setAttribute2(String attribute2) {
product.attribute2 = attribute2;
}
public void setAttribute3(String attribute3) {
product.attribute3 = attribute3;
}
public Product build() {
return product;
}
}
}
我們基本上按照上述思路實現(xiàn)了該代碼赢底,為了一會調(diào)試方便我加了一個toString方法。
可以看到我在這創(chuàng)建了一個product類柏蘑,這個類有三個屬性幸冻,可以是任意類型,為了方便我都給設(shè)置成了string辩越。之后通過內(nèi)部類builder的三個set方法去設(shè)置這三個值嘁扼,通過create方法返回product對象。
在主類中寫如下測試代碼黔攒,可以看到如圖的運行結(jié)果趁啸。
public class Main {
public static void main(String[] args) {
Product.Builder builder = new Product.Builder();
builder.setAttribute1("屬性1");
builder.setAttribute2("屬性2");
builder.setAttribute3("屬性3");
Product product = builder.build();
System.out.println(product.toString());
}
}
但是這段代碼比較繁瑣,并沒有實現(xiàn)像最開始介紹時創(chuàng)建dialog時那么方便督惰,我們可以通過對代碼進行修改來改正這個不方便的地方不傅。
修改builder類的代碼,令它的3個set方法都在賦值后返回它自身赏胚,這樣就完成了访娶。
public static class Builder {
private Product product = new Product();
public Builder setAttribute1(String attribute1) {
product.attribute1 = attribute1;
return this;
}
public Builder setAttribute2(String attribute2) {
product.attribute2 = attribute2;
return this;
}
public Builder setAttribute3(String attribute3) {
product.attribute3 = attribute3;
return this;
}
public Product build() {
return product;
}
}
主類測試運行結(jié)果和上面一樣,就不貼圖了觉阅。
Product.Builder builder = new Product.Builder();
Product product = builder.setAttribute1("屬性1")
.setAttribute2("屬性2")
.setAttribute3("屬性3")
.build();
System.out.println(product.toString());
Builder模式的優(yōu)缺點
優(yōu)點
- 良好的封裝性(調(diào)用者不必知道主類的實現(xiàn)細節(jié)崖疤,只需要對自己關(guān)心的值進行設(shè)置)
- 容易擴展(增加屬性只需要對builder增加一個對應(yīng)的方法即可)
缺點
- 作為中間值產(chǎn)生的builder對象會消耗不必要的內(nèi)存