设计模式-创建者模式总结

创建者模式的特点及使用场景

《Effective Java》—— 创建与销毁对象 一章中有写道:当一个类中有大量的构造参数时,静态方法和构造器已经不能满足对象的实例化,那么我们将考虑构建器。

构建器模式:

  • 1、重叠构造器模式

  • 2、javaBeans模式(自己常用的一种)

  • 3、builder模式

说明:

  • 重叠构造器模式:这种模式下,提供第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,以此类推,最后一个构造器包含所有可选参数。

  • javaBeans模式:调用在各分无参构造器创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。

  • builder模式:builder像个构造器一样,可以对其参数强加约束条件。build方法可以检验这些约束条件。将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对它们进行检验,这一点很重要。如果违反了人格约束条件,build方法就应该抛出IllegalStateException。异常的详细信息应该显示出违反哪个约束条件。

从上不难看出:

  • 重叠构造器模式在参数很多的情况下,客户端代码会很难写,并且难以阅读。

  • javaBeans模式因为构造过程分到了几个调用中,在构造过程中javaBean可能处于不一致的状态,类无法仅仅通过校验构造参数的* 有效性来保证一致性。这样程序员需要付出额外的努力来确保它的线程安全

  • builder模式技能保证像重叠构造器模式那样的安全性,也能保证像javaBeans模式那么好的可读性。

builder模式十分灵活,可以利用单个builder构建多个对象。builder的参数可以在创建对象期间进行调整,也可以随着不同的对象而改变。

代码示例

class DefaultHttpClientFactory { private static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); private static RequestConfig defaultRequestConfig = RequestConfig.custom().build(); private static int mgrMaxTotal = DEFAULT_MAX_TOTAL; //全局最大连接数 private static int mgrDefaultMaxPerRoute = DEFAULT_MAX_PER_ROUTE; //每个主机最大连接数 private static int connReqTimeout = DEFAULT_CONN_REQ_TIMEOUT; //从连接池获取连接超时时间 private static int connTimout = DEFAULT_CONN_TIMEOUT; //发起连接超时时间 private static int connSocketTimeout = DEFAULT_CONN_SOCKET_TIMEOUT; //连接套接字等待时间 public static class Builder { private int mgrMaxTotal = DEFAULT_MAX_TOTAL; //全局最大连接数 private int mgrDefaultMaxPerRoute = DEFAULT_MAX_PER_ROUTE; //每个主机最大连接数 private int connReqTimeout = DEFAULT_CONN_REQ_TIMEOUT; //从连接池获取连接超时时间 private int connTimout = DEFAULT_CONN_TIMEOUT; //发起连接超时时间 private int connSocketTimeout = DEFAULT_CONN_SOCKET_TIMEOUT; //连接套接字等待时间 Builder() { } public Builder maxTotal(int maxTotal) { this.mgrMaxTotal = maxTotal; return this; } public Builder maxPerRoute(int maxPerRoute) { this.mgrDefaultMaxPerRoute = maxPerRoute; return this; } public Builder connReqTimeout(int connReqTimeout) { this.connReqTimeout = connReqTimeout; return this; } public Builder connTimout(int connTimout) { this.connTimout = connTimout; return this; } public Builder connSocketTimeout(int connSocketTimeout) { this.connSocketTimeout = connSocketTimeout; return this; } public DefaultHttpClientFactory build() { return new DefaultHttpClientFactory(this); } } private DefaultHttpClientFactory(Builder builder) { mgrMaxTotal = builder.mgrMaxTotal; mgrDefaultMaxPerRoute = builder.mgrDefaultMaxPerRoute; connReqTimeout = builder.connReqTimeout; connTimout = builder.connTimout; connSocketTimeout = builder.connSocketTimeout; } public static DefaultHttpClientFactory.Builder custom() { return new DefaultHttpClientFactory.Builder(); } public CloseableHttpClient getClient() { cm.setMaxTotal(mgrMaxTotal); // 设置最大连接数 cm.setDefaultMaxPerRoute(mgrDefaultMaxPerRoute); // 设置每个路由最大连接数,每个独立的host为1个路由 RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) .setConnectionRequestTimeout(connReqTimeout)//从连接池获取连接超时时间 .setConnectTimeout(connTimout)//发起连接超时时间 .setSocketTimeout(connSocketTimeout)//连接套接字等待时间 .setRedirectsEnabled(false) .build(); HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(cm); httpClientBuilder.setDefaultRequestConfig(requestConfig); httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)); // 去掉默认的3次重试 CloseableHttpClient httpClient = httpClientBuilder.build(); return httpClient; }} 

个人介绍:

** 高广超** :多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能互联网架构。

本文首发在 高广超的简书博客 (http://www.jianshu.com/p/6d4ca398c120)转载请注明!


分享到:


相關文章: