【设计模式】构建者模式Builder

Builder模式介绍

Builder模式是一步一步创建一个复杂对象的创建型模式,允许用户在不知道内部构建细节的情况下更加精细的控制对象的构造流程。该模式是为了将构建复杂对象的过程和它的部件进行解耦,使得构建过程和部件的表示隔离开来。

Builder的定义

将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。

Builder的使用场景

  1. 相同的方法,不同的执行顺序,产生不同的结果时
  2. 当初始化一个对象特别复杂,比如参数众多,而且很多参数有默认值
  3. 多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又不相同时
  4. 产品类非常复杂,或者产品类中可以调用顺序不同产生了不同的作用。

Builder的UML类图

角色介绍:

  • Product产品类:产品的抽象类
  • Builder:抽象Builder类,规范产品的组件,一般是由子类实现具体的构建过程
  • ConcreteBuilder:具体的Builder类
  • Director:统一组装过程
    在这里插入图片描述

Builder的简单实现

抽象产品:

public abstract class Car {
    protected String mEngine;
    protected String mWheel;
    protected String mSeat;

    protected Car() {
    }

    public void setEngine(String mEngine) {
        this.mEngine = mEngine;
    }

    public void setWheel(String mWheel) {
        this.mWheel = mWheel;
    }

    public abstract void setSeat();

    @Override
    public String toString() {
        return "Car{" +
                "mEngine='" + mEngine + '\'' +
                ", mWheel='" + mWheel + '\'' +
                ", mSeat='" + mSeat + '\'' +
                '}';
    }
}

具体的车

public class BenzCar extends Car {
    protected BenzCar() {
    }

    @Override
    public void setEngine(String mEngine) {
        super.setEngine(mEngine);
    }

    @Override
    public void setSeat() {
        mSeat = "7人高级皮椅";
    }
}

抽象builder类

public abstract class Builder {
    //设置引擎
    public abstract void buildEngine(String engine);
    //设置轮子
    public abstract void buildWheel(String wheel);
    //设置座位
    public abstract void buildSeat();
    //创建car
    public abstract Car create();
}

具体builder类

public class BenzBuilder extends Builder {
    private Car mCar = new BenzCar();

    @Override
    public void buildEngine(String engine) {
        mCar.setEngine(engine);
    }

    @Override
    public void buildWheel(String wheel) {
        mCar.setWheel(wheel);
    }

    @Override
    public void buildSeat() {
        mCar.setSeat();
    }

    @Override
    public Car create() {
        return mCar;
    }
}

Director组装类

public class Director {
    Builder mBuilder = null;

    public Director(Builder builder) {
        this.mBuilder = builder;
    }

    public void construct(String engine, String wheel) {
        mBuilder.buildEngine(engine);
        mBuilder.buildWheel(wheel);
        mBuilder.buildSeat();
    }
}

测试类

public class Test {
    public static void main(String[] args){
        //构建器
        Builder builder = new BenzBuilder();
        //Director
        Director benzDirector = new Director(builder);
        //构建奔驰车
        benzDirector.construct("AMG","防爆胎");
        System.out.println(builder.create().toString());
    }
}

从上述代码中可以看到Director封装了构建复杂产品对象的过程,对外隐藏构建的细节。同样的构建过程可以创建不同的对象。

虽然Builder模式对隐藏构建细节上有很大优势,但是在具体的项目和工程上,起码要配置两个抽象类,两个实体类和一个Director类,结构就会变得复杂。因此在显示开发中,会直接使用一个builder来进行对象的组装,这个builder通过为链式调用,关键是每个setter方法都return this。

Retrofit中Builder模式实现

public final class Retrofit {
  //主要用于缓存,缓存网络请求配置、网络请求方法、转换器等
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
  //okHttp工厂,用于生产okhttp client
  final okhttp3.Call.Factory callFactory;
  //基地址
  final HttpUrl baseUrl;
  //数据转换器工厂集合:比如gson数据转换器
  final List<Converter.Factory> converterFactories;
  //网络请求适配器工厂集合,比如rxjava等
  final List<CallAdapter.Factory> callAdapterFactories;
  //用于执行回调
  final @Nullable Executor callbackExecutor;
  //是否需要立即解析接口中的方法
  final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

  public okhttp3.Call.Factory callFactory() {
    return callFactory;
  }

  public HttpUrl baseUrl() {
    return baseUrl;
  }


  public List<CallAdapter.Factory> callAdapterFactories() {
    return callAdapterFactories;
  }


  public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

  public List<Converter.Factory> converterFactories() {
    return converterFactories;
  }

  public @Nullable Executor callbackExecutor() {
    return callbackExecutor;
  }

  public Builder newBuilder() {
    return new Builder(this);
  }

  //...代码有删减
  
  public static final class Builder {
    //表示retrofit适配的平台,主要有Android、iOS、Java8等,默认下是android平台
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private @Nullable HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    //是否需要提前解析方法和参数
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
    }

    public Builder() {
      this(Platform.get());
    }
    
    //使用现有的retrofit来构建retrofit
    Builder(Retrofit retrofit) {
      platform = Platform.get();
      callFactory = retrofit.callFactory;
      baseUrl = retrofit.baseUrl;

      // Do not add the default BuiltIntConverters and platform-aware converters added by build().
      for (int i = 1,
          size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
          i < size; i++) {
        converterFactories.add(retrofit.converterFactories.get(i));
      }

      // Do not add the default, platform-aware call adapters added by build().
      for (int i = 0,
          size = retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
          i < size; i++) {
        callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
      }

      callbackExecutor = retrofit.callbackExecutor;
      validateEagerly = retrofit.validateEagerly;
    }

    //okhttpclient
    public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }

    
    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }

    //将string转换成httpUrl的方法
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl));
    }

    
    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      //拆分为碎片
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {//必须用|结尾
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

    /** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    /**
     * Add a call adapter factory for supporting service method return types other than {@link
     * Call}.
     */
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    /**
     * The executor on which {@link Callback} methods are invoked when returning {@link Call} from
     * your service method.
     * <p>
     * Note: {@code executor} is not used for {@linkplain #addCallAdapterFactory custom method
     * return types}.
     */
    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = checkNotNull(executor, "executor == null");
      return this;
    }

    /** Returns a modifiable list of call adapter factories. */
    public List<CallAdapter.Factory> callAdapterFactories() {
      return this.callAdapterFactories;
    }

    /** Returns a modifiable list of converter factories. */
    public List<Converter.Factory> converterFactories() {
      return this.converterFactories;
    }

    /**
     * When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate
     * the configuration of all methods in the supplied interface.
     */
    public Builder validateEagerly(boolean validateEagerly) {
      this.validateEagerly = validateEagerly;
      return this;
    }

    /**
    * 将retrofit中的成员变量配置完毕,同时给platform中的转换器converterFactory和callAdapterFactory赋值
    */
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
  }
}

可以看到上述代码中,结构比原始的Builder模式的结构要简单许多。

在Retrofit这个类中,有缓存、callFactory、基地址、converterFactories、callAdapterFactories等成员变量,以及成员变量的setter方法和其他业务逻辑上需要的方法,同时拥有一个内部类Builder,该内部类Builder除了retrofit类中的所有成员和所有的setter方法外,还拥有其他的成员变量:Platform platform,该成员变量是用来描述retrofit所运行的平台,还有如下方法:

  • builder():用来构建retrofit
  • client():配置默认的调用为OkHttpClient

可见,我们只需要调用Retrofit.Builder()方法就能构建出retrofit对象,比上述的Car对象的构建简单许多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值