一、是什么?
将一个对象复杂的构造过程,拆分成若干个的简单过程,让其使用者可以轻松的完成对这个对象的构建。
使构建与表示分离,把构建抽象,使得同样的构建过程可以创建不同的表示。
比如拼乐高积木,新手如果拼一个机器人,不使用建造者模式,需要一个积木一个积木从零开始拼。使用建造者模式,相当于有个机器帮你拼,机器人各个部位的拼法内部已经写好了,你只需要点击拼手臂,机器就把手臂拼好了,使用者不需要知道内部到底怎么拼的。这样有利于使用者快速构建复杂的对象。
二、类图
Product
:构造过程复杂的产品。
Builder
:抽象建造者
ConcreteBuilder
:具体建造者,构建Product对象,并返回。
Director
:导演类,负责指挥组装的类,不过在实际开发中,很少见。
三、代码实现
用建造者模式实现乐高积木的例子。
RobotBuilder
:机器人抽象建造者,将机器人复杂的组装过程分解,并将机器人的构建与具体表示分离。
public abstract class RobotBuilder {
// 拼脑袋
public abstract RobotBuilder buildHead();
// 拼左臂
public abstract RobotBuilder buildLeftArm();
// 拼右臂
public abstract RobotBuilder buildRightArm();
// 拼左腿
public abstract RobotBuilder buildLeftLeg();
// 拼右腿
public abstract RobotBuilder buildRightLeg();
// 组装
public abstract Robot build();
}
Robot
:需要建造的机器人产品(属性为了文章长度,用String,真实情况会是结构更复杂的对象属性)
public class Robot {
public String head;
public String leftArm;
public String rightArm;
public String leftLeg;
public String rightLeg;
}
BumblebeeBuilder
:具体的机器人建造者,封装机器人部位构造的具体实现,由build()最后组装。
/**
* 大黄蜂
*/
public class BumblebeeBuilder extends RobotBuilder{
private Robot robot = new Robot();
private String head;
private String leftArm;
private String rightArm;
private String leftLeg;
private String rightLeg;
@Override
public BumblebeeBuilder buildHead() {
System.out.println("组装大黄蜂的脑袋...");
head = "head";
return this;
}
@Override
public BumblebeeBuilder buildLeftArm() {
System.out.println("组装大黄蜂的左臂...");
leftArm = "leftArm";
return this;
}
@Override
public BumblebeeBuilder buildRightArm() {
System.out.println("组装大黄蜂的右臂...");
rightArm = "rightArm";
return this;
}
@Override
public BumblebeeBuilder buildLeftLeg() {
System.out.println("组装大黄蜂的左腿...");
leftLeg = "leftLeg";
return this;
}
@Override
public BumblebeeBuilder buildRightLeg() {
System.out.println("组装大黄蜂的右腿...");
rightLeg = "rightLeg";
return this;
}
@Override
public Robot build() {
this.robot.head = this.head;
this.robot.leftArm = this.leftArm;
this.robot.rightArm = this.rightArm;
this.robot.leftLeg = this.leftLeg;
this.robot.rightLeg = this.rightLeg;
return this.robot;
}
}
Client
:环境类,建造者的使用者。对于使用者来讲,我想要一个机器人,只需要简单调用几个方法,就可以构造一个复杂的对象。
public class Client {
public static void main(String[] args) {
Robot robot = new BumblebeeBuilder()
.buildHead()
.buildLeftArm().buildRightArm()
.buildLeftLeg().buildRightLeg()
.build();
System.out.println("机器人构建完成。");
}
}
四、与模板方法模式的区别
建造者模式和模板方法模式长的很像,其中同样的构建过程可以创建不同的表示,用到了模板方法模式的思想,因为拼大黄蜂或者擎天柱,构建过程是一样的,都是拼胳膊、拼脑袋等等。
但两者关注的点不同。从使用者的角度来讲,建造者模式中,使用者是指挥建造的,不需要知道具体怎么建造,模式关注过程,使用者关注步骤。模板方法模式中,恰恰相反,模式关注步骤,步骤顺序不能乱,使用者关注步骤的具体实现。
五、实际应用
- StringBuilder、StringBuffer
- Es模板中的请求参数建造
- MyBatis中的SqlSessionFactoryBuilder
- Spring中的BeanDefinitionBuilder
…
六、优缺点
优点:
- 对于使用者来说,使用方便。
- 建造者之间相互独立,扩展性好
缺点:
- 产生很多的对象