跳至主要內容

生成器模式

Mr.Hope...大约 6 分钟

生成器是一种创建型设计模式, 使你能够分步骤创建复杂对象。

与其他创建型模式不同, 生成器不要求产品拥有通用接口。 这使得用相同的创建过程生成不同的产品成为可能。

进一步了解生成器模式 open in new window

使用示例: 生成器模式是 Java 世界中的一个著名模式。 当你需要创建一个可能有许多配置选项的对象时, 该模式会特别有用。

生成器在 Java 核心程序库中得到了广泛的应用:

识别方法: 生成器模式可以通过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 生成器方法通常支持方法链 (例如 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)