設計模式十: 生成器模式(Builder Pattern)
阿新 • • 發佈:2018-12-16
簡介
生成器模式屬於建立型模式的一種, 又叫建造者模式.
生成器模式涉及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模式的物件是最後返回的, 抽象工廠的產品是立即返回.