Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >设计模式-创建者模式总结

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

作者头像
高广超
发布于 2018-12-12 03:15:40
发布于 2018-12-12 03:15:40
45600
代码可运行
举报
文章被收录于专栏:互联网技术栈互联网技术栈
运行总次数:0
代码可运行

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

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

构建器模式:

  • 1、重叠构造器模式
  • 2、javaBeans模式(自己常用的一种)
  • 3、builder模式

说明:

  • 重叠构造器模式:这种模式下,提供第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,以此类推,最后一个构造器包含所有可选参数。
  • javaBeans模式:调用在各分无参构造器创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。
  • builder模式:builder像个构造器一样,可以对其参数强加约束条件。build方法可以检验这些约束条件。将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对它们进行检验,这一点很重要。如果违反了人格约束条件,build方法就应该抛出IllegalStateException。异常的详细信息应该显示出违反哪个约束条件。

从上不难看出:

  • 重叠构造器模式在参数很多的情况下,客户端代码会很难写,并且难以阅读。
  • javaBeans模式因为构造过程分到了几个调用中,在构造过程中javaBean可能处于不一致的状态,类无法仅仅通过校验构造参数的* 有效性来保证一致性。这样程序员需要付出额外的努力来确保它的线程安全
  • builder模式技能保证像重叠构造器模式那样的安全性,也能保证像javaBeans模式那么好的可读性。

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

代码示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
    }
}

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.04.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用Apache HttpClient编写Java爬虫
想要一个使用Apache HttpClient库的爬虫程序。首先,我需要确定用户的需求是什么。他们可能想用Java写一个网络爬虫,用来抓取网页内容。Apache HttpClient是一个常用的HTTP客户端库,用来发送HTTP请求和处理响应。所以,我需要先考虑如何用这个库来构造一个基本的爬虫程序。
华科云商小徐
2025/04/02
1410
聊聊HttpComponentsHttpInvokerRequestExecutor
本文主要研究一下HttpComponentsHttpInvokerRequestExecutor
code4it
2023/10/03
2400
HTTP调用:你考虑到超时、重试、并发了吗?
与执行本地方法不同,进行 HTTP 调用本质上是通过 HTTP 协议进行一次网络请求。网络请求必然有超时的可能性,因此我们必须考虑到这三点:
小熊学Java
2023/07/16
2.8K0
HTTP调用:你考虑到超时、重试、并发了吗?
聊聊HttpComponentsHttpInvokerRequestExecutor
本文主要研究一下HttpComponentsHttpInvokerRequestExecutor
code4it
2023/10/06
1790
聊聊HttpComponentsHttpInvokerRequestExecutor
HttpComponents HttpClient连接池(2)-连接的申请
在上一篇文章里我们主要介绍了 httpclient 连接池的关键类和数据结构,在这里我们主要介绍http连接的申请和释放。
TA码字
2020/04/01
1.3K0
Httpclient核心架构设计
通常,我们使用IE或者safari来访问互联网上的内容,只需要输入资源地址,浏览器便会呈现给你想要的内容。这一切的背后,都是迄今为止在计算机领域最成功的协议–http协议。
用户1205080
2018/10/18
1.2K0
Httpclient核心架构设计
HttpClient 在vivo内销浏览器的高并发实践优化
HttpClient作为Java程序员最常用的Http工具,其对Http连接的管理能简化开发,并且提升连接重用效率;在正常情况下,HttpClient能帮助我们高效管理连接,但在一些并发高,报文体较大的情况下,如果再遇到网络波动,如何保证连接被高效利用,有哪些优化空间。
2020labs小助手
2022/08/15
4240
网关使用 Apache HttpClient 连接池出现异常
两个主机建立网络连接是一个比较复杂的过程,涉及到多个数据包的交换。建立网络连接本身就很耗时间,而 Http 连接需要三次握手,开销就更大。但是可以直接使用已经建立好的 Http 连接,那么花费就比较小。耗时更短,从而提高访问的吞吐量。
BUG弄潮儿
2022/06/30
1.1K0
HttpClient4.X 升级 入门 + http连接池使用
http://blog.csdn.net/shootyou/archive/2011/05/12/6415248.aspx
全栈程序员站长
2022/09/15
6730
Java使用httpclient提交HttpPost请求(form表单提交,File文件上传和传输Json数据)
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。Java后台使用httpclient主要目的是为了模拟客户端的请求。
I Teach You 我教你
2023/07/18
3.9K0
Http 持久连接与 HttpClient 连接池
HTTP协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接。
用户1257393
2018/07/30
2.2K0
Http 持久连接与 HttpClient 连接池
HttpClient使用总结
根据业务量级决定使用同步调用或异步调用:异步回调方式的并发性非常高,缺点是代码可读性一般,在开发中,我会首先选择同步实现,在遇到性能问题后再考虑优化为异步回调方式。在Spring项目中使用HttpClient时,可以借用FactoryBean的概念,编写自己的HttpClientFactoryBean,我在LeanJava中写了一个例子:link
阿杜
2018/08/06
1.2K0
Redis:Jedis连接池JedisPool[通俗易懂]
Jedis提供了连接池JedisPool。由于Jedis对象不是线程安全的,所以一般会从连接池中取出一个Jedis对象独占,使用完毕后再归还给连接池。
全栈程序员站长
2022/10/29
11.1K1
Spring Cloud组件那么多超时设置,如何理解和运用?
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/90724258
亦山
2019/06/01
3.1K0
基于线程池创建HttpClient的请求
public class HttpClientUtils { private final static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); private static CloseableHttpClient httpClient; private static PoolingHttpClientConnectionManager manager; // 连接池管理类 private
Dream城堡
2022/01/07
9760
Java发送Http请求(HttpClient)
HttpClient 是Apache HttpComponents 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是Apache HttpComponents 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
ha_lydms
2023/08/09
1.1K0
Redis 客户端 Jedis 的那点事
作为分布式缓存系统之一,Redis 应用场景较为广泛,落地于不同的行业领域以及业务场景,因此,在整个架构拓扑中起着重要的作用。
Luga Lee
2021/11/22
2K0
Redis 客户端 Jedis 的那点事
Redis 客户端 Jedis 的那点事
Redis ,全称为 “Remote Dictionary Server ”,即:远程字典服务器。一款完全开源免费,基于 C 语言编写,遵守 BSD 协议,高性能的 ( Key/Value ) 分布式内存数据库。其基于内存运行并支持持久化的 NoSQL 数据库, 是当前最热门的 NoSQL 数据库之一,通常也被称之为“数据结构服务器”。Redis 为典型的 C/S 架构,基于 Java 语言平台,其使用 Socket、Redis 的 RESP(Redis Serialization Protocol 即 Redis 序列化协议)协议进行业务处理。作为一款备受欢迎的组件,其主要应用于如下场景中:缓存、计数器、购物车、点赞/打卡、分布式锁等等。
Luga Lee
2021/12/09
1.1K0
Redis 客户端 Jedis 的那点事
HttpClient在多线程环境下踩坑总结
在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态。 而且,从程序日志中判断有线程处于hang住的状态,应该是被阻塞了。
编程随笔
2019/09/11
10.2K0
HttpClient在多线程环境下踩坑总结
由一次线上故障来理解下TCP三握、四挥 & Java堆栈分析到源码的探秘
该服务主要是提供对外的代理接口,大部分接口都会调用第三方接口,获取数据后做聚合处理后,提供给客户端使用。
云爬虫技术研究笔记
2019/11/05
7540
由一次线上故障来理解下TCP三握、四挥 & Java堆栈分析到源码的探秘
推荐阅读
相关推荐
使用Apache HttpClient编写Java爬虫
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验