定義
建造者模式(Builder)是一種對象構建模式,用來封裝一個產品的構造過程,並允許按步驟構造產品。
建造者模式又叫生成器模式,建造者模式屬於創建型模式。
要點
- 經常被用來創建組合結構
- 將複雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象
- 一步一步創建一個複雜的對象,客戶只需要通過指定複雜對象的類型和內容就可以構建它們而不需要知道產品的構建細節
- Product(產品): 一個具體的產品對象。
- Builder(抽象建造者): 創建產品對象各個部件構造規範。
- ConcreteBuilder(具體建造者): 實現接口,執行構建和裝配各個部件。
場景
建房子的過程分爲打樁、砌牆、封頂三個大步驟。不管是普通房子也好,別墅也好都需要經歷這些過程,需要設計一個有彈性的代碼工程來代表建房子的規劃以及所有的變化,當然也需要遵循一系列潛在的複雜建造流程細節。
實現
房子
/**
* 產品: 房子
*/
public class House {
/**
* 地基
*/
private String base;
/**
* 牆面
*/
private String wall;
/**
* 屋頂
*/
private String roof;
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
@Override
public String toString() {
return "House{" +
"base='" + base + '\'' +
", wall='" + wall + '\'' +
", roof='" + roof + '\'' +
'}';
}
}
房子建造者(抽象)
/**
* 房屋建造者(抽象)
*/
public abstract class AbstractHouseBuilder {
/**
* 房子對象
*/
protected House house;
/**
* 建造地基
*/
protected abstract void buildBase();
/**
* 建造牆面
*/
protected abstract void buildWall();
/**
* 建造房頂
*/
protected abstract void buildRoof();
/**
* 建房子的流程
*/
public House buildHouse() {
house = new House();
buildBase();
buildWall();
buildRoof();
return house;
}
}
別墅建造者
/**
* 別墅建造者
*/
public class VillaBuilder extends AbstractHouseBuilder {
@Override
protected void buildBase() {
System.out.println("別墅的地基打30米");
house.setBase("30米深");
}
@Override
protected void buildWall() {
System.out.println("別墅的牆砌25公分寬");
house.setWall("25公分寬");
}
@Override
protected void buildRoof() {
System.out.println("別墅的房頂使用定製琉璃瓦");
house.setRoof("定製琉璃瓦");
}
}
平房建造者
/**
* 平房建造者
*/
public class CottageBuilder extends AbstractHouseBuilder {
@Override
protected void buildBase() {
System.out.println("平房的地基打15米");
house.setBase("15米深");
}
@Override
protected void buildWall() {
System.out.println("平房的牆砌20公分寬");
house.setWall("20公分寬");
}
@Override
protected void buildRoof() {
System.out.println("平房的房頂使用水泥");
house.setRoof("水泥");
}
}
源代碼
總結
-
建造者模式將一個複雜對象的創建過程封裝起來
建造者模式所創建的產品一般具有較多的共同點,其組成部分相似。 -
允許對象通過多個步驟來創建,並且可以改變過程(這和只有一個步驟的工廠模式不同)
可以更加精細地控制產品的創建過程 。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰, 也更方便使用程序來控制創建過程。 -
向客戶隱藏產品的內部實現
客戶不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象。 -
產品的實現可以被替換,因爲客戶只看到一個抽象的接口。
每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 用戶使用不同的具體建造者即可得到不同的產品對象。
注意:
如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,因此在這種情況下,要考慮是否選擇建造者模式。
應用:Java中的 StringBuilder 類就使用了建造者模式。
抽象工廠模式 VS 建造者模式
抽象工廠模式實現對產品家族的創建,一個產品家族是這樣的一系列產品:具有不同分類維度的產品組合,採用抽象工廠模式不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。
而建造者模式則是要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品。