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

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

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

《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;
    }
}

欢迎关注 高广超的简书博客 与 收藏文章 !
欢迎关注 头条号:互联网技术栈

个人介绍:

** 高广超** :多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能互联网架构。目前就职于美团网,负责核心业务研发工作。

本文首发在 高广超的简书博客 转载请注明!

img_7015b3c64a6b1e4a95d4739adf2bbaa0.png
image.png
目录
相关文章
|
1月前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
22 0
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
55 0
|
4月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
23 0
|
3月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
29天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
9天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
19 4
|
14天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
35 2
|
17天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
17天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
19天前
|
设计模式
设计模式(一)简单工厂模式
设计模式(一)简单工厂模式
14 0