設計模式(3)—— 建立型——建造者(Builder)
阿新 • • 發佈:2018-11-19
說明
在眾多開源框架或者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);
}
}
}