定义
将一个复杂对象的创建与它的表示(部件与装配细节)相分离,使得同样的创建过程可以创建不同的表示。
使用场景
- 可以将装配细节封装起来,调用者不必知道具体的产品的内部结构和产生过程。
- 多个部件,都装配到一个对象,不同的装配过程或者不同的装配顺序,产生不同的结果,可以使用该模式
实现方式
产品类
public class Product { private String partA; private String partB; private String partC; //Getter方法和Setter方法省略 }
抽象建造类,不同的建造过程实现Builder接口即可
public abstract class Builder { protected Product product=new Product(); public abstract void PartA(); public abstract void PartB(); public abstract void PartC(); public Product build() { return product; } }
具体建造者。实现抽象接口,构建和装配各个部件
public class ConcreteBuilder extends Builder{ public void PartA(){ ... } public void PartB(){ ... } public void PartC(){ ... } }
指挥者类的代码,该类的作用主要有两个:一方面它隔离了客户与生产过程;另一方面它负责控制产品的生成过程。指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过指挥者类调用建造者的相关方法,返回一个完整的产品对象。
public class Director { private Builder builder; //1 构造方法的方式注入builder对象 public Director(Builder builder) { this.builder=builder; } public Product construct() { builder.PartA(); builder.PartB(); builder.PartC(); return builder.getResult(); } }
客户端调用,无须关心产品对象的具体组装过程,只需确定具体建造者的类型即可。
Builder builder = new ConcreteBuilder(); Director director = new Director(builder); Product product = director.construct();
扩展与思考
建造者模式和工厂方法模式的类图相似,建造者模式关注零件类型和装配工艺(顺序),工厂方法侧重产品创建,不关心组装顺序。
建造者模式的建造者通常可以采用链式编程方式类似
JQuery
,也可以参考Spring的BeanDefinitionBuilder
类。该类只能使用静态方法创建BeanDefinitionBuilder
,其属性赋值方法又返回this
对象本身,可以继续进行属性赋值,最后使用getRawBeanDefinition
或者getBeanDefinition
方法来获取BeanDefinition
。当然也可以使用具体的类创建,但是没有BeanDefinitionBuilder
方便。
public class BeanDefinitionBuilder { public static BeanDefinitionBuilder genericBeanDefinition() { BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); builder.beanDefinition = new GenericBeanDefinition(); return builder; } public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass) { BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); builder.beanDefinition = new GenericBeanDefinition(); builder.beanDefinition.setBeanClass(beanClass); return builder; } public static BeanDefinitionBuilder genericBeanDefinition(String beanClassName) { ... } private AbstractBeanDefinition beanDefinition; private int constructorArgIndex; private BeanDefinitionBuilder() { } public AbstractBeanDefinition getRawBeanDefinition() { return this.beanDefinition; } public AbstractBeanDefinition getBeanDefinition() { this.beanDefinition.validate(); return this.beanDefinition; } public BeanDefinitionBuilder setLazyInit(boolean lazy) { this.beanDefinition.setLazyInit(lazy); return this; } public BeanDefinitionBuilder setAutowireMode(int autowireMode) { beanDefinition.setAutowireMode(autowireMode); return this; } ... }