設計模式(建造者模式)
一、 簡介
建造者模式(Builder Pattern)也叫生成器模式,是一種物件構建模式。它可以將複雜物件的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的物件。
二、UML 類圖
三、建造者模式的實現
案例:
首先我們來看一個簡單的需求現在需要建房子:
1) 修建過程為打樁、砌牆、封頂。
2) 房子有各種各樣的,比如普通房,高樓,別墅,各種房子的過程雖然一樣,但是要求不要相同的。
3) 請編寫程式,完成需求。
常規實現
1、 構建House 類,包含三個屬性打樁、砌牆、封頂
public class House { privateString baise; private String wall; private String roofed; public String getBaise() { return baise; } public void setBaise(String baise) { this.baise = baise; } public String getWall() { return wall; } public void setWall(String wall) {this.wall = wall; } public String getRoofed() { return roofed; } }
2、定義一個抽象類定義三個抽象方法,分別為:打樁、砌牆、封頂
public abstract class HouseBuilder { public abstract void buildBase(); public abstract void buildWall(); public abstract void buildRoofed(); public void buildHouse(){this.buildBase(); this.buildWall(); this.buildRoofed(); } }
3、根據房屋的型別去實現HouseBuilder ,以普通房為例
public class CommonHouse extends HouseBuilder { @Override public void buildBase() { System.out.println("構建地基"); } @Override public void buildWall() { System.out.println("構建圍牆"); } @Override public void buildRoofed() { System.out.println("構建屋頂"); } }
4、模擬一個客戶端
public class ClientTest { public static void main(String[] args) { CommonHouse commonHouse = new CommonHouse(); commonHouse.buildHouse(); } }
常規實現比較好理解,但是這種設計方案將產品和產品的建立過程封裝在了一起,我們可以將產品和產品的建立過程解耦。我們通過建造者模式實現:
1、修改HouseBuilder 類,通過build() 方法返回構建好的房子物件
public abstract class HouseBuilder { protected House house = new House(); public abstract void buildBase(); public abstract void buildWalls(); public abstract void buildRoofed(); public House build(){ return house; } }
2、 定義一個HouseDirector, 將房子的具體建造過程交給constructHouse 方法。
public class HouseDirector { HouseBuilder houseBuilder = null; public HouseDirector(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } public void setHouseBuilder(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } //建造房子的流程,交給指揮者 public House constructHouse(){ houseBuilder.buildBase(); houseBuilder.buildWalls(); houseBuilder.buildRoofed(); return houseBuilder.build(); } }
3、模擬一個客戶端
public class ClientTest { public static void main(String[] args) { CommonHousre commonHousre = new CommonHousre(); HouseDirector director = new HouseDirector(commonHousre); director.constructHouse(); } }
總結:
1、客戶端(使用程式)不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
2、每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 使用者使用不同的具體建造者即可得到不同的產品物件。
3、可以更加精細地控制產品的建立過程 。將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
4、增加新的具體建造者無須修改原有類庫的程式碼,指揮者類針對抽象建造者類程式設計,系統擴充套件方便,符合“開閉原則”。
5、建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。 6、如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,因此在這種情況下,要考慮是否選擇建造者模式。
7、抽象工廠模式 VS 建造者模式,抽象工廠模式實現對產品家族的建立,一個產品家族是這樣的一系列產品:具有不同分類維度的產品組合,採用抽象工廠模式不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。而建造者模式則是要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品。