您现在的位置是:亿华云 > 知识
详解建造者模式(含图例、UML类图、源码示例等)
亿华云2025-10-04 05:56:58【知识】2人已围观
简介来源:mikechen的互联网架构为什么要学设计模式?设计模式有哪些优点?提升查看框架源码能力提升对复杂业务代码的设计能力以及 code 能力为今后面试以及技术进阶夯实基础
来源:mikechen的详解互联网架构
为什么要学设计模式?设计模式有哪些优点?
提升查看框架源码能力提升对复杂业务代码的设计能力以及 code 能力为今后面试以及技术进阶夯实基础今天我们要讲的是设计模式中的建造者模式(Builder)。
建造者模式(Builder)是建造创建型模式中的一种,在面向对象编程中常用,式含必知必会。图例图源
建造者模式(builder):将一个复杂对象的构建与它的表示分离,使得同样的码示构建过程可以创建不同的表示。
例如:
我们要定制一台电脑,详解我们只需要确认配件品牌及型号,建造而不必知道组装电脑的式含这个过程。
这种情况下,我们可以采用建造者模式,类例将配件和组装电脑的码示过程分离,让构建过程和配件都能自由拓展,详解降低两者之间的建造耦合。
02建造者模式的式含 UML 类图为了加深理解,我们来看下建造者模式的 UML 类图。
建造者模式的香港云服务器 4 个重要角色:
Product(产品类):具体需要生成的类对象;Builder(抽象建造者类):为我们需要生成的类对象,构建不同的模块属性,即:公开构建产品类的属性,隐藏产品类的其他功能;ConcreteBuilder(具体建造者类):抽象 Builder 类的实现类,实现抽象 Builder 类定义的所有方法,并且返回一个组建好的对象;Director(指挥者类):用于统一组装流程,确定构建我们的类对象具体有哪些模块属性,在实际应用中可以不需要这个角色,直接通过 client 处理。03建造者模式的应用场景下面是建造者模式的两个典型应用场景。
1)建造者模式在 Java 源码中的体现,较为典型的就是 StringBuilder。
将指定的字符串追加到此字符序列:
@Overridepublic StringBuilder append(CharSequence s) { super.append(s);// 实现过程略 return this;}将此字符序列用其反转形式取代:@Overridepublic StringBuilder reverse() { super.reverse();// 实现过程略 return this;}测试代码:
StringBuilder sb = new StringBuilder("12345");sb.append("67890");sb.reverse();System.out.println(sb);StringBuilder sb1 = new StringBuilder("12345");sb1.reverse();sb1.append("67890");System.out.println(sb1);结果:
System.out: 0987654321System.out: 1422167890根据 StringBuilder 不同方法的不同调用顺序,可以生成不同的字符串,这样的亿华云操作很灵活。
2)建造者模式在很多第三方框架中也有实现。
例如,网络框架 OkHttp3中的 OkHttpClient、Request。
我们来看下 OkHttpClient 、及其内部类 OkHttpClient、Builder 的部分源码:
默认采用 Builder 进行建造:
public OkHttpClient() { this(new Builder());}由 builder 配置分发器、代理、协议以及自定义拦截器等:
OkHttpClient(Builder builder) { this.dispatcher = builder.dispatcher; this.proxy = builder.proxy; this.protocols = builder.protocols; /** 省略大段代码 */ boolean isTLS = false; for (ConnectionSpec spec : connectionSpecs) { isTLS = isTLS || spec.isTls(); } /** 省略大段代码. */ if (interceptors.contains(null)) { throw new IllegalStateException("Null interceptor: " + interceptors); } if (networkInterceptors.contains(null)) { throw new IllegalStateException("Null network interceptor: " + networkInterceptors); }}public static final class Builder { public Builder() { 分发器、协议、代理的默认参数: dispatcher = new Dispatcher(); protocols = DEFAULT_PROTOCOLS; proxySelector = ProxySelector.getDefault(); if (proxySelector == null) { proxySelector = new NullProxySelector(); } } Builder(OkHttpClient okHttpClient) {反向配置分发器、代理、协议:
this.dispatcher = okHttpClient.dispatcher; this.proxy = okHttpClient.proxy; this.protocols = okHttpClient.protocols;新增所有自定义拦截器和自定义网络拦截器:
this.interceptors.addAll(okHttpClient.interceptors); this.networkInterceptors.addAll(okHttpClient.networkInterceptors); }配置代理:
public Builder proxy(@Nullable Proxy proxy) { this.proxy = proxy; return this; }向拦截器链中增加自定义拦截器:
public Builder addInterceptor(Interceptor interceptor) { if (interceptor == null) throw new IllegalArgumentException("interceptor == null"); interceptors.add(interceptor); return this; }build() 方法,生成 OkHttpClient 对象:
public OkHttpClient build() { return new OkHttpClient(this); }}04建造者模式的优缺点优点:使用建造者模式可以使客户端不必知道产品内部组成的细节;
具体的建造者类之间是相互独立的,容易扩展;
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
缺点是产生多余的 Build 对象、源码下载Dirextor 类。05 建造者模式与工厂模式的区别建造者模式与工厂模式都是让创建与表示分离,用来服务相同的目标,让我们写出结构严谨,易懂且易扩展的高质量代码。
但是它们的作用场景、实现方式不同。
建造者模式多出一个 Builder 类,使得创建对象的灵活性大大增加,并且适用于如下场景:
创建一个对象,多个同样的方法的调用顺序不同,产生的结果不同。例如,刚才列举的 StringBuilder;
创建一个对象,特别复杂,参数多,而且很多参数都有默认值。例如,刚才列举的 OkHttpClient Builder 。
总结通过本文,我们了解并掌握了建造者模式的概念、原理、应用场景、优缺点、实现方式等。
只有我们了解了每一种设计模式,实际应用时才能够合理选型,避免因强行使用设计模式、让代码更加不好维护的情况出现。
很赞哦!(7)
相关文章
- 公司名字不但要与其经营理念、活动识别相统一,还要能反映公司理念,服务宗旨、商品形象,从而才能使人看到或听到公司的名称就能产生愉快的联想,对商店产生好感。这样有助于公司树立良好的形象。
- 别再用 Bash 写前端自动化脚本了!
- 你能说说Spring框架中Bean的生命周期吗?
- MySQL高性能学习笔记
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 面试常问的16个C语言问题,你能答上来几个?
- Golang 常见设计模式之装饰模式
- MongoDB即将发布文档数据库3.6版,新功能抢先看!
- 记住那句话,域名向来不属于任何人,谁先买就归谁,购买期过后,域名又不再属于任何人。
- Oracle数据库中直方图对执行计划的影响
热门文章
站长推荐
在此期间,他们每天仍在这里卖大米,在理财方面个人感情有待提高。因为现在是收米的最佳时机。
用Canvas让美女沉浸在音符的海洋里
为什么SQL正在击败NoSQL,这对未来的数据意味着什么
mysql-proxy数据库中间件架构
域名不仅仅是一个简单的网站。对于有长远眼光的公司来说,在运营网站之前确定一个优秀的域名对有长远眼光的公司来说是非常重要的。这对今后的市场营销、产品营销和企业品牌建设都具有十分重要的意义。优秀的域名是企业在市场竞争中获得持久优势的利器。
面试常问的16个C语言问题,你能答上来几个?
Spring Boot 保护敏感配置的四种方法,让你的系统不再裸奔!!!
Mysql大数据备份和增量备份及还原