建造者模式(Builder Pattern)是用来一步一步创建一个复杂对象的的创建型模式,在使用者不知道复杂对象内部时还可以很精确的控制对象的构造流程,将部件和组装分离,使得构建过程和组件都可以自由扩展,降低代码耦合性。
建造者模式分为五个部分:指挥者、抽象建造者、具体建造者、抽象产品、具体产品
指挥者:即图中的 Director,用于构建一个使用了 Builder 接口的对象,控制产品的生产过程
抽象建造者:即图中的 Builder,是一个抽象类,所有具体建造者的父类,规范产品的组建,具体组建由子类完成
具体建造者:即图中的 BuilderA、BuilderB,继承自 Builder,来具体创建产品
抽象产品:及图中的 Product,所有具体产品的父类
具体产品:如图中的 ProductA、ProductB,继承自 Product,建造者创建的具体产品
下面我们通过一个具体的例子来完成建造模式的简单实现,比如我们要组装一辆自行车,包括车架、齿轮、和轮子:
- 新建一个 Bike.java,代表组装完成的自行车产品:
public class Bike {
//车架
private String frame;
//齿轮
private String gear;
//轮子
private String wheel;
//给车子设置车架、齿轮、轮子
public void setFrame(String frame) {
this.frame = frame;
}
public void setGear(String gear) {
this.gear = gear;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
@Override
//重写 toString() 方法
public String toString() {
return "车架是:"+frame+",齿轮是:"+gear+",轮子是:"+wheel;
}
}
- 新建一个 Builder.java,表示抽象建造者:
public abstract class Builder {
//构建车的车架
public abstract void buildFrame(String frame);
//构建车的齿轮
public abstract void buildGear(String gear);
//构建车的轮子
public abstract void buildWheel(String wheel);
//组装自行车,返回一个 Bike
public abstract Bike buildBike();
}
- 新建一个 BikeBuilder.java,表示具体建造者:
public class BikeBuilder extends Builder {
//建造一个自行车
private Bike bike = new Bike();
//重写父类 Builder 的三个方法,实际上调用了 Bike 的三个方法,设置三个部分
@Override
public void buildFrame(String frame) {
bike.setFrame(frame);
}
@Override
public void buildGear(String gear) {
bike.setGear(gear);
}
@Override
public void buildWheel(String wheel) {
bike.setWheel(wheel);
}
//返回的就是这个组装了三个部分的自行车
@Override
public Bike buildBike() {
return bike;
}
}
- 新建一个 Director.java,表示指挥者:
public class Director {
Builder builder = null;
//构造方法传入一个建造者
public Director(Builder builder){
this.builder = builder;
}
//指挥者来指挥组装自行车哪些部分
public void build(String frame,String gear,String wheel){
builder.buildFrame(frame);
builder.buildGear(gear);
builder.buildWheel(wheel);
}
}
- 然后我们来测试一下:
public class Main {
public static void main(String[] args) {
Builder builder = new BikeBuilder();
//创建一个指挥者,让指挥者决定使用哪个具体建造者
Director director = new Director(builder);
director.build("高架","大齿轮","小轮子");
System.out.println(builder.buildBike().toString());
}
}
- 测试结果:
注意的是:本次例子没有多写几个建造者,可以通过指挥者传入不同的建造者来达到建造不同的复杂的对象。而且本次例子也没有使用抽象产品,我们实际开发中中可以使用不同的建造者创建不同的具体产品。
- 建造者模式的优点:
易于解耦,能够通过一样的建造方式来建造不同的复杂对象,而且对于产品和建造过程来说,都易于拓展,封装了建造的过程,隐藏了建造的细节,使得使用者来说十分的简单明了。
- 建造者模式的适用场景:
第一种情况是需要生成的对象有比较复杂的结构
第二种情况是使用相同的建造方法能够创建不同的对象