說明
在衆多開源架構或者jdk源碼中常常出現Builder,build相關的類檔案名或者類名,函數名。其中很多如此命名的原因就是因為使用了建造者(Builder)模式。檢視jdk源碼不難發現,我們常用的StringBuilder類也使用了建造者模式。
建造者模式介紹摘要
- 定義: 将一個複雜對相當建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。
- 特征. 使用者隻需指定需要建造的類型就可以得到它們,建造過程和細節不需要知道
- 類型:建立型
- 适用場景:如果一個對象有非常複雜的内部結構(很多屬性);想把複雜對象的建立和使用分離。
- 優點:
- 封裝性好
- 擴充性好,建造類之間獨立,一定程度上解耦。
- 缺點:
- 産生多餘的Builder對象
- 産品内部發生變化,建造者都要修改,成本較大
代碼實作
場景:我們現在打算入駐網店,是以要送出一份申請資料,申請一個網店店鋪。申請資料送出給業務員(Builder),業務員負責處理相關資料,并将網店的申請結果(Shop類)傳回給申請者。
首先,我們要知道的是具體的建造過程是 由Builder對象完成的。外界直接通過Builder對象來建造擷取一個Shop類的執行個體。具體的UML類圖:

這裡我們隻使用一個Shop類,并且在Shop類中有個内部類。用于建立Shop實體類。我們先直接看外部測試代碼,很容易了解:
public class Test {
public static void main(String[] args) {
// 按需,Build相應的屬性覆寫預設的屬性。
// build()接在buildXX()屬性之後,直接能夠傳回相應的Shop對象執行個體。
Shop shop = new Shop.ShopBuilder()
.buildShopName("My Shop Name")
.buildShopDesc("WelCome to my Shop")
.buildShopPhone("13012345678")
.buildShopPhoto("http://xxx.com/i/img.jpg")
.build();
System.out.println(shop);
}
}
下面是Shop的具體實作類:
public class Shop {
private String name;
private String description;
private String phone;
private String photo;
// 在Builder類内部,通過 return new Shop(this)直接傳回一個Shop對象。
public Shop(ShopBuilder shopBuilder){
this.name = shopBuilder.name;
this.description = shopBuilder.description;
this.phone = shopBuilder.phone;
this.photo = shopBuilder.photo;
}
//為了友善檢視build結果,我們重寫toString方法。
@Override
public String toString() {
return "Shop{" +
"name='" + this.name + '\'' +
", description='" + this.description + '\'' +
", phone='" + this.phone + '\'' +
", photo='" + this.photo + '\'' +
'}';
}
// 這裡是Builder類,負責Build建造。
// 注意1:buildXX()屬性,傳回值為本身,這樣友善鍊式操作。
// 注意2:最後的build()函數,直接build出我們最終想要的實體對象。
public static class ShopBuilder{
private String name = "Default name";
private String description = "Welcome to Default name 's Shop.";
private String phone = "Default number";
private String photo = "Default photo";
public ShopBuilder buildShopName(String name) {
this.name = name;
return this;
}
public ShopBuilder buildShopDesc(String desc) {
this.description = desc;
return this;
}
public ShopBuilder buildShopPhone(String phone) {
this.phone = phone;
return this;
}
public ShopBuilder buildShopPhoto(String photo) {
this.photo = photo;
return this;
}
public Shop build() {
return new Shop(this);
}
}
}