簡單介紹:
建造者模式/生成器模式是一種對象創建型模式之一,用來隱藏複合對象的創建過程,它把複合對象的創建過程加以抽象,通過子類繼承和重載的方式,動態地創建具有複合屬性的對象。
建造者模式實現過程通常分成 2 個步驟:構建(Builder)和裝配(Director)。此處的英文不是對漢字的翻譯而是爲了說明這兩個步驟需要用到的接口類型。
應用場景:
1) 對象的創建:建造者模式是爲對象的創建而設計的模式。如:StringBuilder、DomBuilder、SAXBuilder。
2) 創建的是一個複合對象:被創建的對象爲一個具有複合屬性的複合對象。
3) 關注對象創建的各部分的創建過程:不同的工廠(Builder)對產品屬性有不同的創建方法。
實現方式:
同樣地,我們還是以創建轎車爲例。
實體類:
public class Car {
private Engine engine;
private Tyre tyre;
private Seat seat;
public void intro() {
this.engine.intro();
this.tyre.intro();
this.seat.intro();
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public Tyre getTyre() {
return tyre;
}
public void setTyre(Tyre tyre) {
this.tyre = tyre;
}
public Seat getSeat() {
return seat;
}
public void setSeat(Seat seat) {
this.seat = seat;
}
}
class Engine {
public void intro() {
System.out.println("開得快");
}
}
class Tyre {
public void intro() {
System.out.println("耐磨防滑");
}
}
class Seat {
public void intro() {
System.out.println("坐得舒適");
}
}
Car 類的實例就是一個複合對象。
未使用建造者模式時,客戶端調用如下:
public class Client {
public static void main(String[] args) {
// 創建組裝部件
Engine engine = new Engine();
Tyre tyre = new Tyre();
Seat seat = new Seat();
// 組裝
Car car = new Car();
car.setEngine(engine);
car.setTyre(tyre);
car.setSeat(seat);
car.intro();
}
}
上邊的代碼中,違背了單一職責原則,客戶端與多個類進行了耦合,導致代碼擴展性不強。
接下來我們使用建造者模式讓代碼變得靈活起來。
Builder 接口與實現類,用來實現構建過程:
public interface CarBuilder {
Engine buildEngine();
Tyre buildTyre();
Seat buildSeat();
}
class MyCarBuilder implements CarBuilder {
@Override
public Engine buildEngine() {
return new Engine();
}
@Override
public Tyre buildTyre() {
return new Tyre();
}
@Override
public Seat buildSeat() {
return new Seat();
}
}
此處使用了工廠模式創建組裝轎車的各個部件。很多時候,設計模式並不是單獨使用,而是配合使用。
爲了編寫和測試方便,筆者沒有對 Engine、Tyre 和 Seat 類進行抽象。
Director 接口與實現類,用來實現裝配過程:
public interface CarDirector {
Car directCar();
}
class MyCarDirector implements CarDirector {
private CarBuilder carBuilder;
public MyCarDirector(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
@Override
public Car directCar() {
Engine engine = this.carBuilder.buildEngine();
Tyre tyre = this.carBuilder.buildTyre();
Seat seat = this.carBuilder.buildSeat();
// 裝配
Car car = new Car();
car.setEngine(engine);
car.setTyre(tyre);
car.setSeat(seat);
return car;
}
}
通過 directCar 方法,隱藏複合對象(Car 實例)的創建過程。
客戶端:
public class Client {
public static void main(String[] args) {
CarDirector director = new MyCarDirector(new MyCarBuilder());
Car car = director.directCar();
car.intro();
}
}
現在,客戶端代碼變得簡潔了。因爲建造者模式遵循了依賴倒轉原則,我們只要將客戶端的 Builder 或 Director 替換不同的接口實現類(多態),就能體現出代碼靈活性了。
UML 類圖表示如下: