《设计模式》-- 构建者模式

构建者模式

认识

  • 构建者模式可以分步骤构建复杂对象构建的过程是固定不变的director实现,变化的部分放到builder中实现,定义多个builder的实现类实现不同的过程,而director调用的builder是不变化的
  • director类似一个工厂模式的实现,在director调用不同的builder实现进行构造。保证director的逻辑不要变化,将变化封装到builder实现类中。

思考

  • 构建者模式是将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。抽象工厂可以操作多个产品,而构建者只可以操作一个产品

  • 与工厂模式区别是,工厂模式创建对象时并不需要客户端提供特别多的信息,而构建者模式需要客户端提供创建对象的细节内容。

优缺点

  • 优点

    1. 暴露了创建对象的细节,这样使得建造者模式更加灵活,可替换。
    2. 链式创建对象,具有分步骤创建对象的思想
    3. 客户端和和产品实现类解耦
  • 缺点

    1. 将对象的创建细节暴露

使用场景

  1. 需要生成的产品对象有复杂的内部结构。如果很简单的话,那么使用这个模式可能就没有必要了
  2. 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序
  3. 使用链式结构

UML图

  • 产品类(Product):一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
  • 抽象建造者(Builder):引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
  • 建造者(ConcreateBuilder):实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
  • 导演类(Director):负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。

image

image

代码实现

class Product {  
    private String name;  
    private String type;  
    public void showProduct(){  
        System.out.println("名称:"+name);  
        System.out.println("型号:"+type);  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public void setType(String type) {  
        this.type = type;  
    }  
}  

abstract class Builder {  
    public abstract void setPart(String arg1, String arg2);  
    public abstract Product getProduct();  
}  
class ConcreteBuilder extends Builder {  
    //构建器中new一个产品对象,也可以通过构造方法传入
    private Product product = new Product();  
    //提供返回产品的方法
    public Product getProduct() {  
        return this.product;  
    }  
    //buildName 返回this.product 链式结构
    public Product buildName(String name) {  
        this.product.setName(name); 
        return this.product; 
    }
     //buildType 返回this.product 链式结构
    public Product buildType(String type) {  
        this.product.setType(type); 
        return this.product; 
    }  
}  
/*
 * Director通过Builder创建对象
 * Director 也可以理解为一个工厂模式的实现
 */
public class Director {  
    private Builder builder = new ConcreteBuilder();  
    public Product getAProduct(){  
        builder.buildName("宝马汽车").build("X7");  
        return builder.getProduct();  
    }  
    public Product getBProduct(){  
        builder.buildName("奥迪汽车").build("Q5");
        return builder.getProduct();  
    }  
}  
/**
 * 客户端调用Director
 */
public class Client {  
    public static void main(String[] args){  
        Director director = new Director();  
        Product product1 = director.getAProduct();  
        product1.showProduct();  

        Product product2 = director.getBProduct();  
        product2.showProduct();  
    }  
} 

源码例子

mybatis中大量使用了构建者模式,例如构造Configuration对象

public abstract class BaseBuilder {
  protected final Configuration configuration;
  protected final TypeAliasRegistry typeAliasRegistry;
  protected final TypeHandlerRegistry typeHandlerRegistry;

  public BaseBuilder(Configuration configuration) {
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
  }

  public Configuration getConfiguration() {
    return configuration;
  }
}
//在XMLConfigBuilder对Configuration的各个组件进行组装
public class XMLConfigBuilder extends BaseBuilder {

  private boolean parsed;
  private XPathParser parser;
  private String environment;
  private ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

  private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectionFactoryElement(root.evalNode("reflectionFactory"));
      settingsElement(root.evalNode("settings"));
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }
}

这种构造器模式的使用,实现了显示与构建行为的分离

public final class Environment {
  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;

  public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
    if (id == null) {
      throw new IllegalArgumentException("Parameter 'id' must not be null");
    }
    if (transactionFactory == null) {
        throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");
    }
    this.id = id;
    if (dataSource == null) {
      throw new IllegalArgumentException("Parameter 'dataSource' must not be null");
    }
    this.transactionFactory = transactionFactory;
    this.dataSource = dataSource;
  }

  public static class Builder {
      private String id;
      private TransactionFactory transactionFactory;
      private DataSource dataSource;

    public Builder(String id) {
      this.id = id;
    }

    public Builder transactionFactory(TransactionFactory transactionFactory) {
      this.transactionFactory = transactionFactory;
      return this;
    }

    public Builder dataSource(DataSource dataSource) {
      this.dataSource = dataSource;
      return this;
    }

    public String id() {
      return this.id;
    }

    public Environment build() {
      return new Environment(this.id, this.transactionFactory, this.dataSource);
    }

  }

  public String getId() {
    return this.id;
  }

  public TransactionFactory getTransactionFactory() {
    return this.transactionFactory;
  }

  public DataSource getDataSource() {
    return this.dataSource;
  }

}

public class client{
    public void run(){
         Environment.Builder environmentBuilder = new Environment.Builder(id)
              .transactionFactory(txFactory)
              .dataSource(dataSource);
         Environment ev = environmentBuilder.build();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值