目录
1. 定义
将一个复杂对象的构建与其表示分离(将产品和创建产品的流程进行解耦),使得同样的构建过程可以创建不同的表示。
Product:待创建的对象。
Builder:抽象类,定义了创建Product对象前所需的环节。
ConcreteBuilder:Builder的实现类,实现了创建Product对象前所需的具体环节。
Director:控制Builder创建Product对象的流程。
2. 使用场景
1. 创建某个对象前,需要执行较多的初始化步骤,而客户端不需要知晓具体的创建流程。
2. 某类的构造函数参数较多,而且部分参数是可选时,就可以考虑使用建造者模式来创建对象。
3. 实现方式
3.1 传统的建造者模式
/**
* 产品
*/
public class Bike {
private String name = "unknown"; // 名称,可选参数
private String frame; // 车架
private String saddle; // 车座
private String wheel; // 车轮
private String basket; // 车篮,可选参数
private String backseat; // 车后座,可选参数
public Bike() {
}
public Bike(String frame, String saddle, String wheel) {
this.frame = frame;
this.saddle = saddle;
this.wheel = wheel;
}
public void setName(String name) {
this.name = name;
}
public void setFrame(String frame) {
this.frame = frame;
}
public void setSaddle(String saddle) {
this.saddle = saddle;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public void setBasket(String basket) {
this.basket = basket;
}
public void setBackseat(String backseat) {
this.backseat = backseat;
}
@Override
public String toString() {
return "Bike{" +
"name='" + name + '\'' +
", frame='" + frame + '\'' +
", saddle='" + saddle + '\'' +
", wheel='" + wheel + '\'' +
", basket='" + basket + '\'' +
", backseat='" + backseat + '\'' +
'}';
}
}
/**
* 抽象建造者,定义建造自行车的环节
*/
abstract class Builder {
public abstract void setName();
public abstract void setFrame();
public abstract void setSaddle();
public abstract void setWheel();
public abstract void setBasket();
public abstract void setBackseat();
public abstract Bike build();
}
/**
* 低级自行车建造者
*/
class LowerBuilder extends Builder {
private Bike bike = new Bike();
@Override
public void setName() {
this.bike.setName("低级自行车");
}
@Override
public void setFrame() {
this.bike.setFrame("低级车架");
}
@Override
public void setSaddle() {
this.bike.setSaddle("低级车座");
}
@Override
public void setWheel() {
this.bike.setWheel("低级车轮");
}
@Override
public void setBasket() {
this.bike.setBasket("无车篮");
}
@Override
public void setBackseat() {
this.bike.setBackseat("无后座");
}
@Override
public Bike build() {
return bike;
}
}
/**
* 高级自行车建造者
*/
class SeniorBuilder extends Builder {
private Bike bike = new Bike();
@Override
public void setName() {
this.bike.setName("高级自行车");
}
@Override
public void setFrame() {
this.bike.setFrame("高级车架");
}
@Override
public void setSaddle() {
this.bike.setSaddle("高级车座");
}
@Override
public void setWheel() {
this.bike.setWheel("高级车轮");
}
@Override
public void setBasket() {
this.bike.setBasket("有车篮");
}
@Override
public void setBackseat() {
this.bike.setBackseat("有后座");
}
@Override
public Bike build() {
return bike;
}
}
/**
* 指导者
*/
class Director {
// 控制builder创建产品的流程
public void buildBike(Builder builder) {
builder.setName();
builder.setFrame();
builder.setWheel();
builder.setSaddle();
builder.setBasket();
builder.setBackseat();
}
}
class Test {
public static void main(String[] args) {
Director director = new Director();
Builder lowerBuilder = new LowerBuilder();
director.buildBike(lowerBuilder);
Bike lowerBike = lowerBuilder.build();
System.out.println(lowerBike);
// Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}
Builder seniorBuilder = new SeniorBuilder();
director.buildBike(seniorBuilder);
Bike seniorBike = seniorBuilder.build();
System.out.println(seniorBike);
// Bike{name='高级自行车', frame='高级车架', saddle='高级车座', wheel='高级车轮', basket='有车篮', backseat='有后座'}
}
}
传统的建造者模式解耦了产品和创建流程,ConcreteBuilder负责产品各环节,Director负责组装产品各环节。客户端只需知晓产品的具体建造者ConcreteBuilder,传递给Director便可获得最终产品,而无需知晓创建产品的具体细节。
当然,客户端也可以自己组装产品的创建流程,例如下面的代码:
/**
* 抽象建造者,定义建造自行车的环节
*/
abstract class Builder {
public abstract Builder setName();
public abstract Builder setFrame();
public abstract Builder setSaddle();
public abstract Builder setWheel();
public abstract Builder setBasket();
public abstract Builder setBackseat();
public abstract Bike build();
}
/**
* 低级自行车建造者
*/
class LowerBuilder extends Builder {
private Bike bike = new Bike();
@Override
public Builder setName() {
this.bike.setName("低级自行车");
return this;
}
@Override
public Builder setFrame() {
this.bike.setFrame("低级车架");
return this;
}
@Override
public Builder setSaddle() {
this.bike.setSaddle("低级车座");
return this;
}
@Override
public Builder setWheel() {
this.bike.setWheel("低级车轮");
return this;
}
@Override
public Builder setBasket() {
this.bike.setBasket("无车篮");
return this;
}
@Override
public Builder setBackseat() {
this.bike.setBackseat("无后座");
return this;
}
@Override
public Bike build() {
return bike;
}
}
class Test {
public static void main(String[] args) {
Builder lowerBuilder = new LowerBuilder();
lowerBuilder.setName().setFrame().setSaddle().setWheel().setBasket().setBackseat();
Bike lowerBike = lowerBuilder.build();
lowerBuilder.build();
System.out.println(lowerBike);
// Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}
}
}
上面的代码,去掉了Director,客户端直接通过ConcreteBuilder链式调用,组织创建产品的流程并获取最终产品。
3.2 简化的建造者模式
建造者模式还有一个重要用途,某类的构造函数参数较多,而且部分参数是可选时,就可以考虑使用建造者模式来创建对象。
public class Bike {
private String name = "unknown"; // 名称,可选参数
private String frame; // 车架
private String saddle; // 车座
private String wheel; // 车轮
private String basket; // 车篮,可选参数
private String backseat; // 车后座,可选参数
private Bike(Builder builder) {
this.name = builder.name;
this.frame = builder.frame;
this.saddle = builder.saddle;
this.wheel = builder.wheel;
this.basket = builder.basket;
this.backseat = builder.backseat;
}
public static class Builder {
private String name = "unknown"; // 名称,可选参数
private String frame; // 车架
private String saddle; // 车座
private String wheel; // 车轮
private String basket; // 车篮,可选参数
private String backseat; // 车后座,可选参数
// 此构造函数包含必须的参数
public Builder(String frame, String saddle, String wheel) {
this.frame = frame;
this.saddle = saddle;
this.wheel = wheel;
}
// 提供可选参数的set方法,并返回当前对象,用于后续链式调用
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setBasket(String basket) {
this.basket = basket;
return this;
}
public Builder setBackseat(String backseat) {
this.backseat = backseat;
return this;
}
public Bike build() {
return new Bike(this);
}
}
public void setName(String name) {
this.name = name;
}
public void setFrame(String frame) {
this.frame = frame;
}
public void setSaddle(String saddle) {
this.saddle = saddle;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public void setBasket(String basket) {
this.basket = basket;
}
public void setBackseat(String backseat) {
this.backseat = backseat;
}
@Override
public String toString() {
return "Bike{" +
"name='" + name + '\'' +
", frame='" + frame + '\'' +
", saddle='" + saddle + '\'' +
", wheel='" + wheel + '\'' +
", basket='" + basket + '\'' +
", backseat='" + backseat + '\'' +
'}';
}
}
class Test {
public static void main(String[] args) {
Bike bike = new Bike.Builder("低级车架", "低级车座", "低级车轮")
.setName("低级自行车")
.setBasket("无车篮")
.setBackseat("无后座")
.build();
System.out.println(bike);
// Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}
}
}
上面是简化后的建造者模式,与传统建造者模式相比,不仅去掉了Director,而且Builder移到了Product内部,客户端通过Builder链式调用来创建对象,代码可读性更好。