生成器模式是一种创建型设计模式,它把对象的创建步骤抽象成生成器,并且可以通过指导类(director)对所有生成步骤的先后顺序进行控制。客户端使用指导类并传入相应的生成器,通过指导类的接口便可以得到相应的对象。
以我的理解看,生成器模式中的生成器被用来对生成对象的每一个步骤自身进行控制,比如要产生一辆汽车(最终对象),那么玻璃是用普通玻璃还是防弹玻璃(生成最终对象的一个步骤)。而指导类主要用来设置各个步骤之间的次序与取舍,比如先安装门还是先安装玻璃,要不要安装座垫加热。
生成器模式与抽象工厂模式看起来很像,其实有很多不同。首先抽象工厂模式更注重于“系列”,即要创建的产品族分为不同的系列,同一系列中的产品是固定的,创建的步骤也是固定的。而生成器模式的重点在于对创建过程中每一个步骤的精细控制以及步骤间次序的控制,这些在抽象工厂模式中是不方便进行控制的(甚至需要修改或创建新的工厂抽象类)。
下面以一辆汽车的生产为例。
首先是汽车类:
interface CarPlan {
void setWheel(String wheel);
void setFrame(String frame);
void setEngine(String engine);
void setWidget(String widget);
}
class Car implements CarPlan {
private String myWheel;
private String myFrame;
private String myEngine;
private String myWidget;
void setWheel(String wheel) {
myWheel = wheel;
}
void setFrame(String frame) {
myFrame = frame;
}
void setEngine(String engine) {
myEngine = engine;
}
void setWidget(String widget) {
myWidget = widgetl
}
}
然后创建生成器:
interface Builder {
void buildWheel();
void buildFrame();
void buildEngine();
void buildWidget();
Car getCar();
}
//一个廉价车生成器
class CheapBuilder implements Builder {
Car cheapCar = new Car();
Car getCar() {
return cheapCar;
}
void buildWheel() {
cheapCar.setWheel("cheap wheel");
}
void buildFrame() {
cheapCar.setFrame("cheap frame");
}
void buildEngine() {
cheapCar.setEngine("cheap engine");
}
void buildWidget() {
cheapCar.setWidget("no widget");
}
}
//一个平价车生成器
class EconomicBuilder implements Builder {
Car economicCar = new Car();
Car getCar() {
return economicCar;
}
void buildWheel() {
cheapCar.setWheel("cheap wheel");
}
void buildFrame() {
cheapCar.setFrame("expensive frame");
}
void buildEngine() {
cheapCar.setEngine("cheap engine");
}
void buildWidget() {
cheapCar.setWidget("economic widget");
}
}
创建指导类:
class Director {
private Builder builder;
director(Builder bld) {
builder = bld;
}
void produceCar() {
//这里对步骤进行控制
builder.buildFrame();
builder.buildWidget();
builder.buildWheel();
builder.buildEngine();
}
Car getCar() {
builder.getCar();
}
}
客户端使用:
public class Test {
public static void main(String[] args) {
Builder bld = new EconomicBuilder();
Director director = new Director(bld);
director.produceCar();
Car car = director.getCar();
}
总结
当使用生成器模式的时候,最大的疑问就是,和工厂方法和抽象方法有什么区别?其实目的都是创建一个对象,只是生成器的模式控制的粒度为创建对象的每一个步骤,让每一个步骤具有扩展性,让创建对象的步骤具有扩展性,这种野心更加细粒度。而工厂模式并不是控制到步骤,它只是希望创建对象的行为具有可扩展性。
生成器使生成对象的步骤有扩展性,工厂使获取对象具有扩展性。
抽取变化:对象的步骤细节不同,步骤的顺序不同。