无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发动机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者模式对其进行设计与描述,建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。
在软件开发中,也存在大量类似汽车一样的复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。
复杂对象相当于一辆有待建造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。
造者模式(
Builder Pattern
):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式属于对象创建型模式。建造者模式又可以称为生成器模式。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
建造者模式包含如下角色:
Builder
:抽象建造者ConcreteBuilder
:具体建造者Director
:导演者Product
:产品角色首先,是产品类:
/**
* 产品类.
*
* Created by blinkfox on 2016/10/8.
*/
public class Product {
private String part1;
private String part2;
/* getter 和 setter方法. */
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
}
其实,是抽象的建造者Builder
接口和具体的建造者ConcreteBuilder
类:
/**
* 抽象的建造者.
*
* Created by blinkfox on 2016/10/8.
*/
public interface Builder {
/**
* 产品建造部分1.
*/
void buildPart1();
/**
* 产品建造部分2.
*/
void buildPart2();
/**
* 得到建造的产品.
*
* @return 产品
*/
Product getResult();
}
/**
* 具体的建造者实现类.
*
* Created by blinkfox on 2016/10/8.
*/
public class ConcreteBuilder implements Builder {
/** 产品. */
private Product product = new Product();
/**
* 产品建造部分1.
*/
@Override
public void buildPart1() {
product.setPart1("编号:95757");
}
/**
* 产品建造部分2.
*/
@Override
public void buildPart2() {
product.setPart2("名称:小机器人");
}
/**
* 得到建造的产品.
*
* @return 产品
*/
@Override
public Product getResult() {
return product;
}
}
最后,导演者Director
类:
/**
* 导演者类.
*
* Created by blinkfox on 2016/10/8.
*/
public class Director {
/** 当前需要的建造者对象. */
private Builder builder;
/**
* 构造方法.
*
* @param builder
*/
public Director(Builder builder) {
this.builder = builder;
}
/**
* 产品构造方法,负责调用各个零件建造方法.
*/
public void construct() {
builder.buildPart1();
builder.buildPart2();
}
}
以下是建造者模式的客户端场景类:
/**
* 建造者模式的客户端场景类.
*
* Created by blinkfox on 2016/10/8.
*/
public class BuilderClient {
/**
* 主入口方法.
*
* @param args 数组参数
*/
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
System.out.println(product.getPart1());
System.out.println(product.getPart2());
}
}
抽象建造者类中定义了产品的创建方法和返回方法;
建造者模式的结构中还引入了一个导演者类Director
,该类的作用主要有两个:一方面它隔离了客户与生产过程;另一方面它负责控制产品的生成过程。导演者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过导演者类调用建造者的相关方法,返回一个完整的产品对象
在客户端代码中,无须关心产品对象的具体组装过程,只需确定具体建造者的类型即可,建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。
建造者模式的优点:
建造者模式的缺点:
在以下情况下可以使用建造者模式:
construct()
建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造