簡介
生成器模式屬於建立型模式的一種, 又叫建造者模式.
生成器模式涉及4個關鍵角色:產品(Product),抽象生成器(builder),具體生成器(ConcreteBuilder),指揮者(Director).
實現層面上, 產品定義了需要什麼樣的物件, 具體生成器完成了物件的具體表示. 如果只需要一個具體的構建者,那麼抽象生成器角色和指揮者可以省略(如StringBuilder).
意圖
將一個複雜物件的構建與它的表示分離, 使得同樣的構建過程可以建立不同的表示.
類圖
實現
一. 定義產品
/**
* Car 有很多成員變數, 當然成員可能是一些複雜型別, 這裡簡化只定義一些基本型別
*/
@Data
public class Car {
private String engine; //發動機
private String chassis; // 底盤
private String body; //車身
private String wheels; //輪子
private String equipment; //構件, 可選
private String radar;// 雷達, 可選
}
二. 定義抽象生成器角色
/**
* 抽象生成器角色,定義每個元件的建立返回型別為本型別, 這樣就可以使用鏈式程式設計方式了
* 定義了返回最終產品的介面
*/
public abstract class AbstractCarBuilder {
//產品
private Car car = new Car();
protected Car getCar(){
return car;
}
public abstract AbstractCarBuilder setEngine();
public abstract AbstractCarBuilder setChassis();
public abstract AbstractCarBuilder setBody();
public abstract AbstractCarBuilder setWheels();
public abstract AbstractCarBuilder setEquipment();
public abstract AbstractCarBuilder setRadar();
// 返回產品
public Car build(){
return car;
}
}
三. 定義具體的生成器實現,這裡定義兩個
// 第一個實現
public class BMWCarBuilder extends AbstractCarBuilder {
public AbstractCarBuilder setEngine() {
Car car = this.getCar();
car.setEngine("BMW setEngine");
return this;
}
public AbstractCarBuilder setChassis() {
Car car = this.getCar();
car.setChassis("BMW setChassis");
return this;
}
public AbstractCarBuilder setBody() {
Car car = this.getCar();
car.setBody("BMW setBody");
return this;
}
public AbstractCarBuilder setWheels() {
Car car = this.getCar();
car.setWheels("BMW setWheels");
return this;
}
public AbstractCarBuilder setEquipment() {
Car car = this.getCar();
car.setEquipment("BMW setEquipment");
return this;
}
public AbstractCarBuilder setRadar() {
Car car = this.getCar();
car.setRadar("BMW setRadar");
return this;
}
}
//第二個實現
public class QQCarBuilder extends AbstractCarBuilder {
public AbstractCarBuilder setEngine() {
Car car = this.getCar();
car.setEngine("QQ setEngine");
return this;
}
public AbstractCarBuilder setChassis() {
Car car = this.getCar();
car.setChassis("QQ setChassis");
return this;
}
public AbstractCarBuilder setBody() {
Car car = this.getCar();
car.setBody("QQ setBody");
return this;
}
public AbstractCarBuilder setWheels() {
Car car = this.getCar();
car.setWheels("QQ setWheels");
return this;
}
//沒有此元件, 不做任何事情
public AbstractCarBuilder setEquipment() {
return this;
}
//沒有此元件, 不做任何事情
public AbstractCarBuilder setRadar() {
return this;
}
}
四. 定義指揮者
/**
* 指揮者角色, 用來定義構建複雜物件的演算法
* 這裡同時也定義了測試的main方法
*/
public class Director {
private AbstractCarBuilder builder;
public Director(AbstractCarBuilder builder) {
this.builder = builder;
}
public Car BuildCar(){
// 鏈式構建,並返回最終的結果
return builder
.setWheels()
.setRadar()
.setEngine()
.setChassis()
.setBody()
.setEquipment()
.build();
}
public static void main(String[] args) {
Director director = new Director(new QQCarBuilder());
Car car = director.BuildCar();
System.out.println(car.toString());
director = new Director(new BMWCarBuilder());
car = director.BuildCar();
System.out.println(car.toString());
}
}
總結
如果一個物件需要的成員變數較多, 也就是初始化所需引數過多, 過程比較複雜的話, 那麼它就適合使用Builder模式.
優點: 物件分解為元件;將物件構造封裝;構造過程可控;
缺點: 增加了類的數量.
與抽象工廠模式的區別: 二者都可以建立複雜物件, 不同的是抽象工廠強調建立一系列的產品物件, 而生成器模式著重於一步步建立一個複雜物件. Builder模式的物件是最後返回的, 抽象工廠的產品是立即返回.