详解建造者模式(含图例、UML类图、源码示例等)

发布时间:2025-05-18 01:44:13 作者:益华网络 来源:undefined 浏览量(1) 点赞(1)
摘要:来源:mikechen的互联网架构 为什么要学设计模式?设计模式有哪些优点?提升查看框架源码能力提升对复杂业务代码的设计能力以及 code 能力为今后面试以及技术进阶夯实基础 今天我们要讲的是设计模式中的建造者模式(Builder)。

来源:mikechen的互联网架构

为什么要学设计模式?设计模式有哪些优点?

提升查看框架源码能力提升对复杂业务代码的设计能力以及 code 能力为今后面试以及技术进阶夯实基础

今天我们要讲的是设计模式中的建造者模式(Builder)

建造者模式(Builder)是创建型模式中的一种,在面向对象编程中常用,必知必会。

01建造者模式的定义

建造者模式(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 。

总结

通过本文,我们了解并掌握了建造者模式的概念、原理、应用场景、优缺点、实现方式等。

只有我们了解了每一种设计模式,实际应用时才能够合理选型,避免因强行使用设计模式、让代码更加不好维护的情况出现。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!