作用
生成器模式是一种创建型设计模式,能够分布创建复杂对象。允许使用相同的创建代码生成不同类型和形式的对象。
结构
生成器接口(Builder)
声明在所有类型生成器中通用的产品构造步骤。
具体生成器(Concrete Builders)
提供构造过程的不同实现,具体生成器也可以构造不遵循通用接口的产品呢。
产品(Products)
是最终生成的对象。由不同生成器构造的产品无需属于同一类层次结构或接口。
主管(Director)
定义调用构造步骤的顺序,这样就可以创建和复用特定的产品配置。
客户端
必须将某个生成器对象和主管类关联,只需通过主管类构造函数的参数进行一次性关联即可,伺候主管类就能使用生成器对象完成所有构造任务。
场景
现在一个装修公司要建一套房子,但是每套房子的配置不一样,有的是独卫,有的是双卫。有的要求先做水电工步骤,有的要求先做泥木工步骤。这种场景如果我们把建房子当作一个对象,要求当作构造参数的话,参数一旦变多,代码的可读性就会下降,而且要求整改的时候会修改到业务代码违反了开闭原则。
解决方法
对于每一种房子都任命一个对它施工流程非常熟悉的项目经理(Dierctor),你只要给他提要求(Builder),他自己会按照规定去指定编排一套施工流程完成并交付给你。
实现
// 生成器接口
public interface Builder {
void buildStepA();
void buildStepB();
void buildStepC();
}
// 具体生成器
public class ConcreteBuilderA implements Builder {
private Villa result;
@Override
public void buildStepA() {
System.out.println("做独卫");
}
@Override
public void buildStepB() {
System.out.println("泥木工程用粗砂");
}
@Override
public void buildStepC() {
System.out.println("水电工程开关用松下");
}
public Villa getResult() {
return result;
}
}
public class ConcreteBuilderB implements Builder {
private Department result;
@Override
public void buildStepA() {
System.out.println("做双卫");
}
@Override
public void buildStepB() {
System.out.println("泥木工程用细沙");
}
@Override
public void buildStepC() {
System.out.println("水电工程开关用西门子");
}
public Department getResult() {
return result;
}
}
// 具体产品
public class Villa {
public Villa() {
System.out.println("这是别墅");
}
}
public class Department {
public Department() {
System.out.println("这是公寓");
}
}
// 主管
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
// 根据不同的要求规划不同的流程
public void make(String type) {
if (type.equals("别墅")){
builder.buildStepA();
builder.buildStepC();
builder.buildStepB();
}else if(type.equals("公寓")){
builder.buildStepC();
builder.buildStepA();
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
// 业主提供了B建筑方式
ConcreteBuilderB builderB = new ConcreteBuilderB();
// 将该建筑方式告知了项目经理
Director director = new Director(builderB);
// 造别墅,建造方式在make方法里订好了
director.make("别墅");
System.out.println("===========");
// 造公寓
director.make("公寓");
// 获得结果
Department result = builderB.getResult();
}
}
总结
- 可以避免较多参数构造函数的方法
- 可以分步创建对象,并可以指定创建的方式
- 主管类接收具体的创建方法,根据不同的要求创建不同形式的产品
- 缺点是会增加多个具体生成器或产品类