设计模式十: 生成器模式(Builder Pattern)
简介
生成器模式属于创建型模式的一种, 又叫建造者模式.
生成器模式涉及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模式的对象是最后返回的, 抽象工厂的产品是立即返回.