将一个复杂对象的建立与它的表示分离,使得一样的建立过程能够建立不一样的表示java
假设构造函数中有十个可选参数,那么调用该函数会很是不方便;所以,须要重载这个构造函数,新建几个只有较少参数的简化版。可是这些构造函数仍需调用主构造函数,传递一些默认数值来代替省略掉的参数算法
class Pizza { Pizza(int size) { ... } Pizza(int size, boolean cheese) { ... } Pizza(int size, boolean cheese, boolean pepperoni) { ... } // ...
1) 能够改变一个产品的内部表示 Builder对象提供给导向器一个构造产品的抽象接口,产品是经过抽象接口构造的。该接口使得生成器能够隐藏这个产品的表示和内部结构。当时须要改变产品的内部结构,只须要定义一个新的生成器app
2) 将构造代码和表示代码分开 Builder模式经过封装一个复杂对象的建立和表示方式提升了对象的模块性。每一个Concretebuilder包含了建立和装配一个特定产品的全部代码。Director能够复用它以在相同部件集合的基础上构建不一样的productide
3)对构造过程进行更精细的控制 Builder模式是在导向器的控制下,一步一步构造产品的。仅当产品完成时,导向器才从生成器中取回它。所以,builder接口相比其余建立型模式能更好的反映产品的构造过程,这使咱们能够更精细的控制构造过程函数
builders/Builder.java: 通用生成器接口ui
package builder.builders; import builder.cars.CarType; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; /** * @author GaoMing * @date 2021/7/18 - 9:58 * Builder interface defines all possible ways to configure a product */ public interface Builder { void setCarType(CarType type); void setSeats(int seats); void setEngine(Engine engine); void setTransmission(Transmission transmission); void setTripComputer(TripComputer tripComputer); void setGPSNavigator(GPSNavigator gpsNavigator); }
builders/CarBuilder.java: 汽车生成器this
package builder.builders; import builder.cars.Car; import builder.cars.CarType; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; /** * @author GaoMing * @date 2021/7/18 - 10:01 */ public class CarBuilder implements Builder{ private CarType type; private int seats; private Engine engine; private Transmission transmission; private TripComputer tripComputer; private GPSNavigator gpsNavigator; public void setCarType(CarType type) { this.type = type; } @Override public void setSeats(int seats) { this.seats = seats; } @Override public void setEngine(Engine engine) { this.engine = engine; } @Override public void setTransmission(Transmission transmission) { this.transmission = transmission; } @Override public void setTripComputer(TripComputer tripComputer) { this.tripComputer = tripComputer; } @Override public void setGPSNavigator(GPSNavigator gpsNavigator) { this.gpsNavigator = gpsNavigator; } public Car getResult() { return new Car(type, seats, engine, transmission, tripComputer, gpsNavigator); } }
builders/CarManualBuilder.java: 汽车手册生成器spa
package builder.builders; import builder.cars.CarType; import builder.cars.Manual; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; /** * @author GaoMing * @date 2021/7/18 - 10:03 * Unlike other creational patterns, Builder can construct unrelated products, * which don't have the common interface. * In this case we build a user manual for a car, using the same steps as we * built a car. This allows to produce manuals for specific car models, * configured with different features. */ public class CarManualBuilder implements Builder{ private CarType type; private int seats; private Engine engine; private Transmission transmission; private TripComputer tripComputer; private GPSNavigator gpsNavigator; @Override public void setCarType(CarType type) { this.type = type; } @Override public void setSeats(int seats) { this.seats = seats; } @Override public void setEngine(Engine engine) { this.engine = engine; } @Override public void setTransmission(Transmission transmission) { this.transmission = transmission; } @Override public void setTripComputer(TripComputer tripComputer) { this.tripComputer = tripComputer; } @Override public void setGPSNavigator(GPSNavigator gpsNavigator) { this.gpsNavigator = gpsNavigator; } public Manual getResult() { return new Manual(type, seats, engine, transmission, tripComputer, gpsNavigator); } }
cars/Car.java: 汽车产品3d
package builder.cars; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; /** * @author GaoMing * @date 2021/7/18 - 9:48 * Car is a product class */ public class Car { private final CarType carType; private final int seats; private final Engine engine; private final Transmission transmission; private final TripComputer tripComputer; private final 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; } public CarType getCarType() { return carType; } public double getFuel() { return fuel; } public void setFuel(double fuel) { this.fuel = fuel; } public int getSeats() { return seats; } public Engine getEngine() { return engine; } public Transmission getTransmission() { return transmission; } public TripComputer getTripComputer() { return tripComputer; } public GPSNavigator getGpsNavigator() { return gpsNavigator; } }
cars/Manual.java: 手册产品code
package builder.cars; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; /** * @author GaoMing * @date 2021/7/18 - 9:56 * Car manual is another product. Note that it does not have the same ancestor as a Car. They are not related */ public class Manual { private final CarType carType; private final int 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 += "Type of car: " + carType + "\n"; info += "Count of seats: " + seats + "\n"; info += "Engine: volume - " + engine.getVolume() + "; mileage - " + engine.getMileage() + "\n"; info += "Transmission: " + transmission + "\n"; if (this.tripComputer != null) { info += "Trip Computer: Functional" + "\n"; } else { info += "Trip Computer: N/A" + "\n"; } if (this.gpsNavigator != null) { info += "GPS Navigator: Functional" + "\n"; } else { info += "GPS Navigator: N/A" + "\n"; } return info; } }
cars/CarType.java
package builder.cars; /** * @author GaoMing * @date 2021/7/18 - 9:51 */ public enum CarType { CITY_CAR, SPORTS_CAR, SUV }
components/Engine.java: 产品特征 1
package builder.components; /** * @author GaoMing * @date 2021/7/18 - 9:27 * feature of a car */ 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 boolean isStarted(){ return started; } public void go(double mileage){ if(started){ this.mileage += mileage; }else { System.err.println("Cannot go(), you must start engine first!"); } } public double getVolume(){ return volume; } public double getMileage(){ return mileage; } }
components/GPSNavigator.java: 产品特征 2
package builder.components; /** * @author GaoMing * @date 2021/7/18 - 9:33 * Another feature of a car */ public class GPSNavigator { private String route; public GPSNavigator(){ this.route = "221b, Baker Street, London to Scotland Yard, 8-10 Broadway, London"; } public GPSNavigator(String manualRoute){ this.route = manualRoute; } public String getRoute(){ return route; } }
components/Transmission.java: 产品特征 3
package builder.components; /** * @author GaoMing * @date 2021/7/18 - 9:35 * Another feature of a car */ public enum Transmission { SINGLE_SPEED, MANUAL, AUTOMATIC, SEMI_AUTOMATIC }
components/TripComputer.java: 产品特征 4
package builder.components; import builder.cars.Car; /** * @author GaoMing * @date 2021/7/18 - 9:48 * Another feature of a car */ public class TripComputer { private Car car; public void setCar(Car car){ this.car = car; } public void showFuellevel(){ System.out.println("Fuel level: " + car.getFuel()); } public void showStatus(){ if(this.car.getEngine().isStarted()){ System.out.println("Car is started"); }else { System.out.println("Car isn't started"); } } }
director/Director.java: 主管控制生成器
package builder.director; import builder.cars.CarType; import builder.components.Engine; import builder.components.GPSNavigator; import builder.components.Transmission; import builder.components.TripComputer; import builder.builders.Builder; /** * @author GaoMing * @date 2021/7/18 - 10:08 * Director defines the order of building steps. It works with a builder object * through common Builder interface. Therefore it may not know what product is * being built. */ public class Director { public void constructSportsCar(Builder builder) { builder.setCarType(CarType.SPORTS_CAR); builder.setSeats(2); builder.setEngine(new Engine(3.0, 0)); builder.setTransmission(Transmission.SEMI_AUTOMATIC); builder.setTripComputer(new TripComputer()); builder.setGPSNavigator(new GPSNavigator()); } public void constructCityCar(Builder builder) { builder.setCarType(CarType.CITY_CAR); builder.setSeats(2); builder.setEngine(new Engine(1.2, 0)); builder.setTransmission(Transmission.AUTOMATIC); builder.setTripComputer(new TripComputer()); builder.setGPSNavigator(new GPSNavigator()); } public void constructSUV(Builder builder) { builder.setCarType(CarType.SUV); builder.setSeats(4); builder.setEngine(new Engine(2.5, 0)); builder.setTransmission(Transmission.MANUAL); builder.setGPSNavigator(new GPSNavigator()); } }
Demo.java: 客户端代码
package builder; import builder.builders.CarBuilder; import builder.builders.CarManualBuilder; import builder.cars.Car; import builder.cars.Manual; import builder.director.Director; /** * @author GaoMing * @date 2021/7/18 - 10:13 * Demo class. Everything comes together here. */ public class demo { public static void main(String[] args) { Director director = new Director(); // Director gets the concrete builder object from the client // (application code). That's because application knows better which // builder to use to get a specific product. CarBuilder builder = new CarBuilder(); director.constructSportsCar(builder); // The final product is often retrieved from a builder object, since // Director is not aware and not dependent on concrete builders and // products. Car car = builder.getResult(); System.out.println("Car built:\n" + car.getCarType()); CarManualBuilder manualBuilder = new CarManualBuilder(); // Director may know several building recipes. director.constructSportsCar(manualBuilder); Manual carManual = manualBuilder.getResult(); System.out.println("\nCar manual built:\n" + carManual.print()); } }
OutputDemo.txt: 执行结果
Car built: SPORTS_CAR Car manual built: Type of car: SPORTS_CAR Count of seats: 2 Engine: volume - 3.0; mileage - 0.0 Transmission: SEMI_AUTOMATIC Trip Computer: Functional GPS Navigator: Functional
生成器重点关注如何分步生成复杂对象。 抽象工厂专门用于生产一系列相关对象。 抽象工厂会立刻返回产品, 生成器则容许你在获取产品前执行一些额外构造步骤。
Composite一般是由Builder生成的
识别方法: 生成器模式能够经过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 生成器方法一般支持方法链 (例如 someBuilder->setValueA(1)->setValueB(2)->create() )