建造者模式(Bulider模式)
前面我们已经学习了工厂模式:通过定义一个创建对象的接口,然后让其子类自己决定实例化哪一个工厂类,使我们创建对象时不会对客户端暴露创建逻辑。工厂模式属于一种创建型模式,今天我们要来学习另外一种创建型模式:建造者模式
模式的定义与特点
建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
通俗点来说在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。计算机由多个部件构成,各个部件可以灵活选择。这类产品的创建无法用前面介绍的工厂模式完整描述。可以说工厂方法模式注重零部件的创建过程,而建造者模式注重零部件的组装过程,两者可以结合使用。
模式的结构与实现
建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成,现在我们来分析其基本结构和实现方法。
结构
建造者(Builder)模式的主要角色如下。
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。(类比抽象工厂)
具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。(类比具体工厂)
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。(这也是建造者模式较工厂模式的特点所在)
其结构图如图 1 所示。
2. 模式的实现
图 1 给出了建造者(Builder)模式的主要结构,其相关类的代码如下。
(1) 产品角色:包含多个组成部件的复杂对象。
<package 建造者模式;
//定义一个产品角色:里面包含多个部件的复杂对象。
public class Product {
private String partA;// 部件A
private String partB;// 部件B
private String partC;// 部件C
public String getPartA() {
return partA;
}
public void setPartA(String partA) {
this.partA = partA;
}
public String getPartB() {
return partB;
}
public void setPartB(String partB) {
this.partB = partB;
}
public String getPartC() {
return partC;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void show() {
System.out.println("产品建造完毕");
}
}
`>
2抽象建造者:包含创建产品各个子部件的抽象方法。
package 建造者模式;
//抽象建造者:包含创建产品各个子部件的抽象方法。
public abstract class Builder {
// 首先创建一个产品对象
Product p = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
public Product getResult() {
return p;
}
}
(3) 具体建造者:实现了抽象建造者接口。
package 建造者模式;
//具体建造者:实现了抽象建造者类。
public class SpecificBuilder extends Builder {
@Override
public void buildPartA() {
// TODO Auto-generated method stub
// 在这里面建造部件A
p.setPartA("建造A");
System.out.println("建造A");
}
@Override
public void buildPartB() {
// TODO Auto-generated method stub
// 在这里面建造部件B
p.setPartB("建造B");
System.out.println("建造B");
}
@Override
public void buildPartC() {
// TODO Auto-generated method stub
// 在这里面建造部件C
p.setPartC("建造c");
System.out.println("建造C");
}
}
//此时已经完成了产品各个部件的建造。只需根据需要完成相应的构建也就是组装,成一个完整的产品
(4) 指挥者:调用建造者中的方法完成复杂对象的创建。
package 建造者模式;
//产品的构建组装由指挥者来完成
//指挥者:调用建造者中的方法完成复杂对象(产品)的创建。
public class Leader {
// 指挥建造者
private Builder builder;
public Leader(Builder builder) {
this.builder = builder;
}
//产品构建与组装方法
public Product construct() {// 根据需要来调整部件的组装顺序
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
// 最后返回由这个产品
}
}
(5) 客户类。
package 建造者模式;
public class Customer {
public static void main(String[] args) {
Builder builder = new SpecificBuilder();
Leader leader = new Leader(builder);
Product product1 = leader.construct();// 指挥建造产品
product1.show();
}
}
整个过程下来产品(复杂对象)完成
总结
该模式的主要优点如下:
各个具体的建造者相互独立,有利于系统的扩展。
客户端不必知道产品内部组成的细节,便于控制细节风险。
其缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,该模式会增加很多的建造者类。
建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。