生成器模式
...大约 6 分钟
生成器是一种创建型设计模式, 使你能够分步骤创建复杂对象。
与其他创建型模式不同, 生成器不要求产品拥有通用接口。 这使得用相同的创建过程生成不同的产品成为可能。
使用示例: 生成器模式是 Java 世界中的一个著名模式。 当你需要创建一个可能有许多配置选项的对象时, 该模式会特别有用。
生成器在 Java 核心程序库中得到了广泛的应用:
java.lang.StringBuilder#append()
(非同步
)java.lang.StringBuffer#append()
(同步
)java.nio.ByteBuffer#put()
(还有CharBuffer
、ShortBuffer
、IntBuffer
、LongBuffer
、FloatBuffer
和DoubleBuffer
)javax.swing.GroupLayout.Group#addComponent()
java.lang.Appendable
的所有实现
识别方法: 生成器模式可以通过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 生成器方法通常支持方法链 (例如 someBuilder.setValueA(1).setValueB(2).create()
)。
分步制造汽车
在本例中, 生成器模式允许你分步骤地制造不同型号的汽车。
示例还展示了生成器如何使用相同的生产过程制造不同类型的产品 (汽车手册)。
主管控制着构造顺序。 它知道制造各种汽车型号需要调用的生产步骤。 它仅与汽车的通用接口进行交互。 这样就能将不同类型的生成器传递给主管了。
最终结果将从生成器对象中获得, 因为主管不知道最终产品的类型。 只有生成器对象知道自己生成的产品是什么。
项目结构

生成器
CarBuilder.java: 通用生成器接口
// 生成器:生成汽车或相关说明书
public interface CarBuilder {
CarBuilder setCarType(CarType carType);
CarBuilder setSeats(Integer seats);
CarBuilder setEngine(Engine engine);
CarBuilder setTransmission(Transmission transmission);
CarBuilder setTripComputer(TripComputer tripComputer);
CarBuilder setGpsNavigator(GPSNavigator gpsNavigator);
Object build();
void reset();
}
CarProductBuilder.java:汽车生成器
//汽车实体生成器
public class CarProductBuilder implements CarBuilder {
private CarType carType;
private Integer seats;
private Engine engine;
private Transmission transmission;
private TripComputer tripComputer;
private GPSNavigator gpsNavigator;
@Override
public CarBuilder setCarType(CarType carType) {
this.carType = carType;
return this;
}
@Override
public CarBuilder setSeats(Integer seats) {
this.seats = seats;
return this;
}
@Override
public CarBuilder setEngine(Engine engine) {
this.engine = engine;
return this;
}
@Override
public CarBuilder setTransmission(Transmission transmission) {
this.transmission = transmission;
return this;
}
@Override
public CarBuilder setTripComputer(TripComputer tripComputer) {
this.tripComputer = tripComputer;
return this;
}
@Override
public CarBuilder setGpsNavigator(GPSNavigator gpsNavigator) {
this.gpsNavigator = gpsNavigator;
return this;
}
@Override
public Car build(){
Car car = new Car(carType, seats, engine, transmission, tripComputer, gpsNavigator);
this.reset();
return car;
}
@Override
public void reset() {
this.carType = null;
this.engine = null;
this.seats = 0;
this.transmission = null;
this.tripComputer = null;
this.gpsNavigator = null;
}
}
CarManualBuilder.java:汽车手册生成器
public class CarManualBuilder implements CarBuilder {
private CarType carType;
private Integer seats;
private Engine engine;
private Transmission transmission;
private TripComputer tripComputer;
private GPSNavigator gpsNavigator;
@Override
public CarBuilder setCarType(CarType carType) {
this.carType = carType;
return this;
}
@Override
public CarBuilder setSeats(Integer seats) {
this.seats = seats;
return this;
}
@Override
public CarBuilder setEngine(Engine engine) {
this.engine = engine;
return this;
}
@Override
public CarBuilder setTransmission(Transmission transmission) {
this.transmission = transmission;
return this;
}
@Override
public CarBuilder setTripComputer(TripComputer tripComputer) {
this.tripComputer = tripComputer;
return this;
}
@Override
public CarBuilder setGpsNavigator(GPSNavigator gpsNavigator) {
this.gpsNavigator = gpsNavigator;
return this;
}
@Override
public Manual build() {
Manual manual = new Manual(carType, seats, engine, transmission, tripComputer, gpsNavigator);
this.reset();
return manual;
}
@Override
public void reset() {
this.carType = null;
this.engine = null;
this.seats = 0;
this.transmission = null;
this.tripComputer = null;
this.gpsNavigator = null;
}
}
产品
Car.java:汽车
@Data
public class Car {
private CarType carType;
private int seats;
private Engine engine;
private Transmission transmission;
private TripComputer tripComputer;
private GPSNavigator gpsNavigator;
private double fuel = 0;
public Car(CarType carType, int seats, Engine engine, Transmission transmission,
TripComputer tripComputer, GPSNavigator gpsNavigator) {
this.carType = carType;
this.seats = seats;
this.engine = engine;
this.transmission = transmission;
this.tripComputer = tripComputer;
if (this.tripComputer != null) {
this.tripComputer.setCar(this);
}
this.gpsNavigator = gpsNavigator;
}
}
Manual.java:手册
@Data
public class Manual {
private final CarType carType;
private final Integer seats;
private final Engine engine;
private final Transmission transmission;
private final TripComputer tripComputer;
private final GPSNavigator gpsNavigator;
public Manual(CarType carType, int seats, Engine engine, Transmission transmission,
TripComputer tripComputer, GPSNavigator gpsNavigator) {
this.carType = carType;
this.seats = seats;
this.engine = engine;
this.transmission = transmission;
this.tripComputer = tripComputer;
this.gpsNavigator = gpsNavigator;
}
public String print() {
String info = "";
info += "汽车类型:" + carType + "\n";
info += "座位数量:" + seats + "\n";
info += "发动机:容积 - " + engine.getVolume() + ";里程 - " + engine.getMileage() + "\n";
info += "变速箱:" + transmission + "\n";
if (this.tripComputer != null) {
info += "行车电脑:正常工作" + "\n";
} else {
info += "行车电脑:不可用" + "\n";
}
if (this.gpsNavigator != null) {
info += "GPS导航仪:正常工作" + "\n";
} else {
info += "GPS导航仪:不可用" + "\n";
}
return info;
}
}
组件
汽车类型
//组件类:汽车类型
public enum CarType {
CITY_CAR, SPORTS_CAR, SUV
}
发动机
// 组件类:发动机
@Data
public class Engine {
private final double volume;
private double mileage;
private boolean started;
public Engine(double volume, double mileage) {
this.volume = volume;
this.mileage = mileage;
}
public void on() {
started = true;
}
public void off() {
started = false;
}
public void go(double mileage) {
if (started) {
this.mileage += mileage;
} else {
System.err.println("不能起步,你需要先点火");
}
}
}
GPS导航仪
// 组件类:GPS导航仪
@Data
public class GPSNavigator {
private final String route;
public GPSNavigator() {
this.route = "从单位到家";
}
public GPSNavigator(String manualRoute) {
this.route = manualRoute;
}
@Override
public String toString() {
return route;
}
}
变速箱
// 组件类:变速箱
public enum Transmission {
SINGLE_SPEED, MANUAL, AUTOMATIC, SEMI_AUTOMATIC
}
行车电脑
// 组件类:行车电脑
@Getter
@Setter
public class TripComputer {
private Car car;
public void showFuelLevel() {
System.out.println("燃油油位: " + car.getFuel());
}
public void showStatus() {
if (this.car.getEngine().isStarted()) {
System.out.println("汽车启动");
} else {
System.out.println("汽车未启动");
}
}
@Override
public String toString() {
String start = this.car.getEngine().isStarted() ? "汽车启动" : "汽车未启动";
return "燃油油位: " + car.getFuel()+start;
}
}
主管
Director.java: 主管控制生成器
// 主管类:管理生成器的生成流程
public class Director {
// 生成运动汽车,什么类型取决于实现类的build方法
public Object constructSportsCar(CarBuilder builder) {
return builder
.setCarType(CarType.SPORTS_CAR)
.setSeats(2)
.setEngine(new Engine(3.0, 0))
.setTransmission(Transmission.SEMI_AUTOMATIC)
.setTripComputer(new TripComputer())
.setGpsNavigator(new GPSNavigator())
.build();
}
// 生成城市汽车
public Object constructCityCar(CarBuilder builder) {
return builder
.setCarType(CarType.CITY_CAR)
.setSeats(2)
.setEngine(new Engine(1.2, 0))
.setTransmission(Transmission.AUTOMATIC)
.setTripComputer(new TripComputer())
.setGpsNavigator(new GPSNavigator())
.build();
}
// 生成SUV汽车
public Object constructSUV(CarBuilder builder) {
return builder
.setCarType(CarType.SUV)
.setSeats(4)
.setEngine(new Engine(2.5, 0))
.setTransmission(Transmission.MANUAL)
.setGpsNavigator(new GPSNavigator())
.build();
}
}
使用
public class Main {
public static void main(String[] args) {
// 主管
Director director = new Director();
// 汽车生成器
CarBuilder carBuilder = new CarProductBuilder();
// 生成城市汽车:主管 负责管理 生成器,直接生产出产品
Car cityCar = (Car) director.constructCityCar(carBuilder);
System.out.println(cityCar);
// 生成SUV汽车
Car suvCar = (Car) director.constructSUV(carBuilder);
System.out.println(suvCar);
//生成运动汽车手册
CarBuilder manualBuilder = new CarManualBuilder();
Manual sportManual = (Manual) director.constructSportsCar(manualBuilder);
System.out.println(sportManual.print());
//生成suv汽车手册
Manual suvManual = (Manual) director.constructSUV(manualBuilder);
System.out.println(sportManual.print());
//也可以不使用主管,直接使用生成器,不设置座位和电脑
Car diyCar = (Car) carBuilder.setCarType(CarType.SPORTS_CAR)
.setEngine(new Engine(30.0, 10))
.setTransmission(Transmission.SEMI_AUTOMATIC)
.setGpsNavigator(new GPSNavigator())
.build();
System.out.println(diyCar);
}
}
结果:
Car(carType=CITY_CAR, seats=2, engine=Engine(volume=1.2, mileage=0.0, started=false), transmission=AUTOMATIC, tripComputer=燃油油位: 0.0汽车未启动, gpsNavigator=从单位到家, fuel=0.0)
Car(carType=SUV, seats=4, engine=Engine(volume=2.5, mileage=0.0, started=false), transmission=MANUAL, tripComputer=null, gpsNavigator=从单位到家, fuel=0.0)
汽车类型:SPORTS_CAR
座位数量:2
发动机:容积 - 3.0;里程 - 0.0
变速箱:SEMI_AUTOMATIC
行车电脑:正常工作
GPS导航仪:正常工作
汽车类型:SPORTS_CAR
座位数量:2
发动机:容积 - 3.0;里程 - 0.0
变速箱:SEMI_AUTOMATIC
行车电脑:正常工作
GPS导航仪:正常工作
Car(carType=SPORTS_CAR, seats=0, engine=Engine(volume=30.0, mileage=10.0, started=false), transmission=SEMI_AUTOMATIC, tripComputer=null, gpsNavigator=从单位到家, fuel=0.0)