簡介
建造者模式又稱為builder模式,一般用來建構複雜對象,将複雜對象的建立與表示分離,使用者不需要了解建造的過程和細節。完整的建造者模式的結構模型如下:

完整的建造者模式包含四個角色:
builder:指定建立對象的各個部件的接口;
ConcreteBuilder:具體建造者,實作builder的接口;
product:最終建構成的具體産品;
director:指揮者直接和客戶進行需求溝通,并将客戶建立産品的請求劃分為對各個零件的建立請求,再将這些請求委托給具體建造者建造;
模式實作
以網上訂購電腦舉例,産品為電腦(部件包括主機、顯示器、電源線三部分),指揮者相當于電商平台,而建造者為電腦廠家。使用者和平台溝通,平台委托廠家建立電腦并轉交給使用者。
産品,即電腦類:
@Data
public class Computer implements Serializable {
...
}
建造者接口:
public interface ComputerBuilder {
void buildMainEngine(); // 建造主機
void buildMonitor(); // 建造顯示器
void buildPowerCord(); // 建造電源線
Computer returnComputer(); // 返還電腦産品
}
具體建造者:
public class ComputerConcreteBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildMainEngine() {
System.out.println("建立主機。。");
}
@Override
public void buildMonitor() {
System.out.println("建立顯示器。。");
}
@Override
public void buildPowerCord() {
System.out.println("建立電源線。。");
}
@Override
public Computer returnComputer() {
return computer;
}
}
指揮者:
@NoArgsConstructor
public class ComputerDirector {
private ComputerBuilder computerBuilder;
public ComputerDirector(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer buildComputer() {
computerBuilder.buildMainEngine();
computerBuilder.buildMonitor();
computerBuilder.buildPowerCord();
return computerBuilder.returnComputer();
}
}
實際使用:
public static void main(String[] args) {
Computer computer = new ComputerDirector().buildComputer();
}
這樣,一個完整的建造者模式流程就完成了。
建造者模式一般一個具體建造者隻對應一個産品,如果有多個産品,則添加多個具體建造者。
模式退化
省略抽象建造者角色
如果确定隻需要一個具體建造者的話,那麼抽象建造者是可以省略的,抽象建造者角色的存在是為了規範具體建造者的行為,如果系統隻有一個具體建造者,那麼這個規範者角色就不需要了。
省略指揮者角色
如果抽象建造者角色被省略了,那麼指揮者角色也可以被省略,這時候具體建造者同時扮演指揮者和建造者兩個角色。
省略單獨的産品角色
這種情況适用于建造者構造的對象就是建造者自身,建造者同時扮演指揮者、建造者、産品三個角色。
jdk中的建造者模式
jdk中的建造者模式常見的就是SringBuffer和StringBuilder了,其中非線程安全的StringBuilder最為常用。AbstractStringBuilder作為抽象建造者,StringBuidler作為具體建造者,建造的對象是String,通過toString方法傳回。
此外,常用的鍊式調用也可以視為建造者模式,例如:
@Data
@Accessors(chain = true)
public class Computer implements Serializable {
private static final long serialVersionUID = 3991323827696929155L;
private String mainEngine;
private String monitor;
private String powerCord;
public static void main(String[] args) {
Computer computer = new Computer().setMainEngine("主機").setMonitor("顯示器").setPowerCord("電源線");
}
}
其中Computer為産品,
setMainEngine()
、
setMonitor()
setPowerCord()
是建構産品的部件方法,這種就是極簡類型的建造者模式。
與其他模式對比
與抽象工廠模式
在抽象工廠模式中,每一次工廠對象被調用時都會傳回一個産品對象,這個産品位于不同的産品等級結構中的一環,可能是一個最終的産品的一部分,而用戶端後續把産品組裝到成一個更大更複雜的産品;建造者模式則傳回一個完整的、最終的産品。
抽象工廠模式中,用戶端直接調用工廠方法擷取所需産品對象,而建造者模式中,用戶端可以通過指揮者間接擷取對象,且建造者類側重于一步步構造一個複雜對象,傳回一個完整的對象。
還使用上面例子,抽象工廠模式傳回産品族中的一個産品,例如隻傳回電腦主機;而建造者模式直接傳回整個電腦。
與模闆模式
當建造者模式退化到沒有指揮者,且抽象建造者使用抽象類,這樣完全可能變為模闆模式,隻要将具體建構産品部件方法的順序固定到返還産品方法中,并将返還産品不可重寫,就是一個合格的模闆模式。
實質上,兵無常勢,水無常形,實際代碼中嚴格按照設計模式定義的實作并不多,大多是退化之後的模式,而很多模式退化之後都非常相似,甚至可以互相轉化。