建造者模式是创建型设计模式。一个产品常由不同的零件构成,我们把这些零件叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象,也就是不同的零件。建造模式思想是:把创建对象过程中,使用了哪些零件,零件之间有什么关系等统统封装起来,可以使客户需要知道这些的情况下得到所需要的对象。
建造者模式包含4个角色:
- 抽象建造者(builder):给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口应该独立于业务逻辑。
- 具体建造者(ConcreteBuilder):产品的实际生产者。.实现
抽象建造者
所声明的接口,给出一步一步地完成创建产品实例的操作,并在建造过程完成后,提供产品的实例。 - 指导者(Director):调用
具体建造者
以创建产品对象。指导者知道具体如何构造产品,只是指挥具体建造者生产。 产品(Product):产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
看起来建造者模式跟抽象工厂模式(参见这里)很相似,我们先来看看建造者模式的结构,这里同样用汽车做例子:
具体代码实现:
底盘和引擎的实现请参考这里,这里是一样的,就不再重复了。
产品:
public class Car {
private Chassis chassis;
private Engine engine;
// Getters and Setters
// ...
}
抽象建造者、具体建造者:
public interface CarBuilder {
void buildChassis();
void buildEngine();
Car retrieveCar();
}
public class BenzCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildChassis() { car.setChassis(new ChassisBenz()); }
@Override
public void buildEngine() { car.setEngine(new EngineBenz()); }
@Override
public Car retrieveCar() { return car; }
}
public class BMWCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildChassis() { car.setChassis(new ChassisBMW()); }
@Override
public void buildEngine() { car.setEngine(new EngineBMW()); }
@Override
public Car retrieveCar() { return car; }
}
指导者:
public class Director {
// 指挥建造者生产一辆Benz汽车
public Car buildABenzCar() {
CarBuilder builder = new BenzCarBuilder();
builder.buildChassis();
builder.buildEngine();
return builder.retrieveCar();
}
// 指挥建造者生产一辆BMW汽车
public Car buildABMWzCar() {
CarBuilder builder = new BMWCarBuilder();
builder.buildChassis();
builder.buildEngine();
return builder.retrieveCar();
}
}
客户:
public class Client {
Director director = new Director();
public Car orderABenzCar(){
return director.buildABenzCar();
}
public Car orderABMWzCar(){
return director.buildABMWzCar();
}
}
class ClientTest {
public static void main(String[] args) {
Client client = new Client();
Car car = client.orderABMWzCar();
System.out.println("A car is created.");
System.out.printf("CHASSIS: %s\n", car.getChassis().identify());
System.out.printf("ENGINE: %s", car.getEngine().identify());
}
}
运行结果:
A car is created.
CHASSIS: this is a Chassis of BMW.
ENGINE: this is an Engine of BMW.
与抽象工厂模式
相比, 建造者模式
返回一个组装好的完整产品 ,而抽象工厂模式
返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
在抽象工厂模式
中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式
中,客户一般不直接调用建造者的相关方法,而是通过指导者类来指挥生成对象(有时客户和指导者可以二合为一),包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。也就是说,建造者模式
更侧重于对象生成的过程,这对于复杂对象的构造十分有意义。
如果将抽象工厂模式
看成汽车配件生产工厂 ,生产一个产品族的产品,那么建造者模式
就是一个汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车。
由此我们可以总结出,什么时候可心使用建造者模式:
需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。
需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。
在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。