1. 程式人生 > >設計模式(3)—— 建立型——建造者(Builder)

設計模式(3)—— 建立型——建造者(Builder)

說明

在眾多開源框架或者jdk原始碼中常常出現Builderbuild相關的類檔名或者類名,函式名。其中很多如此命名的原因就是因為使用了建造者(Builder)模式。檢視jdk原始碼不難發現,我們常用的StringBuilder類也使用了建造者模式。

建造者模式介紹摘要

  • 定義: 將一個複雜對相當構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
  • 特徵. 使用者只需指定需要建造的型別就可以得到它們,建造過程和細節不需要知道
  • 型別:建立型
  • 適用場景:如果一個物件有非常複雜的內部結構(很多屬性);想把複雜物件的建立和使用分離。
  • 優點:
    • 封裝性好
    • 擴充套件性好,建造類之間獨立,一定程度上解耦。
  • 缺點:
    • 產生多餘的Builder物件
    • 產品內部發生變化,建造者都要修改,成本較大

程式碼實現

場景:我們現在打算入駐網店,所以要提交一份申請資料,申請一個網店店鋪。申請資料提交給業務員(Builder),業務員負責處理相關資料,並將網店的申請結果(Shop類)返回給申請者。

首先,我們要知道的是具體的建造過程是 由Builder物件完成的。外界直接通過Builder物件來建造獲取一個Shop類的例項。具體的UML類圖:
建造者例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);
        }

    }
}