Java设计模式:建造者模式之经典与流式的三种实现(四)

本文将深入探讨Java中建造者模式的两种实现方式:经典建造者与流式建造者。建造者模式是一种创建型设计模式,它允许你构建复杂对象的步骤分解,使得对象的创建过程更加清晰和灵活。我们将通过示例代码详细解释这两种实现方式,并分析它们各自的特点和使用场景。

[参见]:

Java设计模式:核心概述(一)

Java设计模式:单例模式之六种实现方式详解(二)

Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

目录

    • 一、前言
    • 二、建造者模式的使用场景
    • 三、建造者模式的三种实现方式
      • 3.1 经典建造者模式
      • 3.2 流式建造者模式
      • 3.3 使用Lombok库实现流式建造者模式
    • 四、建造者模式的注意事项
    • 五、结语

一、前言

开发中,我们经常需要创建具有多个属性或配置选项的复杂对象。直接通过构造函数或大量的setter方法来设置这些属性可能会导致代码的可读性和维护性下降。建造者模式通过提供一个建造者类来封装复杂对象的创建过程,使得客户端代码可以更加简洁和清晰地构建对象。

二、建造者模式的使用场景

  1. 当对象有多个构造函数参数时:如果一个类的构造函数需要多个参数,而这些参数中有些是可选的,那么使用建造者模式可以更加清晰地表达对象的创建过程,避免构造函数的参数列表过长和混乱。

  2. 当对象的构建过程需要多个步骤时:如果对象的创建过程涉及多个步骤,并且这些步骤的顺序很重要,那么建造者模式可以确保这些步骤按照正确的顺序执行,并提供一种灵活的方式来调整这些步骤。

  3. 当需要创建不同配置的对象变体时:如果需要根据不同的配置选项创建对象的多个变体,那么建造者模式可以提供一种清晰的方式来表示这些配置选项,并根据需要构建不同的对象变体。

  4. 当对象的构建过程需要复杂的逻辑时:如果对象的构建过程涉及复杂的逻辑,如验证参数的有效性、计算属性的默认值等,那么建造者模式可以将这些逻辑封装在建造者类中,使客户端代码更加简洁和清晰。

在这里插入图片描述


三、建造者模式的三种实现方式

Java中,实现建造者设计模式通常有两种主要方式:经典的建造者模式(也称为分步构建器)和流式建造者模式(也称为流畅接口构建器或链式调用构建器)。第三种借用lomback自动生成流式建造者模式,所以实际是两种方式。

3.1 经典建造者模式

经典建造者模式通常包括一个产品类、一个抽象建造者接口、一个具体建造者类和一个指挥者类(可选)。产品类包含需要设置的属性和访问器方法。抽象建造者接口定义了构建产品所需的各个步骤。具体建造者类实现了抽象建造者接口,并提供了设置产品属性和获取构建好的产品对象的方法。

然而,在实际应用中,我们往往可以省略指挥者类,直接在客户端代码中操作具体建造者来构建产品对象。这种方式简化了经典建造者模式的结构,但仍然保留了其逐步构建对象的优点。

代码:

// 产品类  
public class Product {  private String partA;  private String partB;  private String partC;  // 构造方法可以是私有的,因为建造者模式可以控制对象的构建过程  private Product() {}  public String getPartA() {  return partA;  }  public void setPartA(String partA) {  this.partA = partA;  }  // 省略其他getter和setter方法...  // 静态内部类作为具体建造者  public static class Builder {  private Product product;  public Builder() {  product = new Product();  }  public Builder setPartA(String partA) {  product.partA = partA;  return this; // 返回当前Builder实例,以便链式调用  }  public Builder setPartB(String partB) {  product.partB = partB;  return this;  }  public Builder setPartC(String partC) {  product.partC = partC;  return this;  }  // 创建并返回产品对象  public Product build() {  return product;  }  }  
}  // 客户端代码  
public class Client {  public static void main(String[] args) {  Product product = new Product.Builder()  .setPartA("This is part A")  .setPartB("This is part B")  .setPartC("This is part C")  .build();  System.out.println(product.getPartA());  // 省略访问其他部分...  }  
}

Product 类有一个静态内部类 Builder,它负责构建 Product 对象。客户端代码通过调用 Builder 的方法来设置产品的各个部分,并最终调用 build() 方法来获取构建好的产品对象。

3.2 流式建造者模式

流式建造者模式是经典建造者模式的一种变体,它更加强调链式调用的流畅性。在流式建造者模式中,产品类通常包含一个静态内部类作为流式建造者。这个内部类提供了设置产品属性的方法,并返回自身的实例以支持链式调用。最后,通过一个build()方法返回构建好的产品对象。

流式建造者模式省略了经典建造者模式中的抽象建造者接口和指挥者类,使得代码更加简洁和直观。同时,通过链式调用的方式设置产品属性,可以提高代码的可读性和编写的灵活性。

代码:

// 产品类  
public class Product {  private String partA;  private String partB;  private String partC;  // 私有构造方法,防止直接实例化  private Product() {}  // 省略getter方法...  // 静态内部类作为流式建造者  public static class Builder {  private String partA;  private String partB;  private String partC;  public Builder withPartA(String partA) {  this.partA = partA;  return this;  }  public Builder withPartB(String partB) {  this.partB = partB;  return this;  }  public Builder withPartC(String partC) {  this.partC = partC;  return this;  }  // 创建产品对象  public Product build() {  Product product = new Product();  product.partA = this.partA;  product.partB = this.partB;  product.partC = this.partC;  return product;  }  }  
}  // 客户端代码  
public class Client {  public static void main(String[] args) {  Product product = new Product.Builder()  .withPartA("This is part A")  .withPartB("This is part B")  .withPartC("This is part C")  .build();  // 省略访问产品属性的代码...  }  
}

Builder 类的每个设置方法都返回 Builder 类型的实例(即 this),从而允许链式调用。这种方式使得客户端代码更加简洁和易读。注意,在这个实现中,Product 类的构造方法是私有的,以防止外部直接实例化。所有的属性设置都是通过 Builder 进行的。

3.3 使用Lombok库实现流式建造者模式

Lombok 是一个 Java 库,它可以通过注解来简化 Java 代码,例如自动生成 getter、setter、equals、hashCode 和 toString 方法等。其中,@Builder 注解就是用来实现建造者模式的一个简化工具。

使用 Lombok 的 @Builder 注解,你不需要手动编写建造者模式的代码。只需要在类定义上添加 @Builder 注解,Lombok 就会在编译时自动生成相应的建造者类。

下面是一个使用 Lombok @Builder 注解来实现建造者模式的代码:

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;@Getter
@Setter
@Builder
public class Person {private String name;private int age;private String address;// 使用 Lombok @Builder 注解后,无需再手动编写建造者模式的代码// Lombok 会在编译时自动生成一个名为 Person.PersonBuilder 的内部类// 下面是如何使用生成的建造者类来构建 Person 对象的示例public static void main(String[] args) {Person person = Person.builder().name("John Doe").age(30).address("123 Main St").build();System.out.println(person);}
}

在这个例子中,我们定义了一个 Person 类,并使用了 @Getter@Setter@Builder 注解。@Getter@Setter 注解分别用于生成 getter 和 setter 方法,而 @Builder 注解则用于生成建造者模式的代码。

main 方法中,我们使用 Person.builder() 方法来获取一个 PersonBuilder 实例,然后通过链式调用设置 nameageaddress 属性,最后调用 build() 方法来构建 Person 对象。

以上使用 Lombok 的 @Builder 注解所生成的代码在编译时会创建一个内部类,这个内部类通常命名为 类名Builder,在这个例子中是 PersonBuilder。这个内部类会包含对应类中所有字段的设置方法以及一个 build() 方法来创建目标对象。

生成的代码大致相当于手动实现的流式建造者模式,因为它允许通过链式调用的方式来设置对象的属性。不过,由于 Lombok 自动处理了这些细节,用户无需手动编写这些代码。

假设没有 Lombok,并且我们要手动实现上述 Person 类的建造者模式,代码可能看起来像这样:

public class Person {private String name;private int age;private String address;private Person(Builder builder) {this.name = builder.name;this.age = builder.age;this.address = builder.address;}public static class Builder {private String name;private int age;private String address;public Builder() {}public Builder name(String name) {this.name = name;return this;}public Builder age(int age) {this.age = age;return this;}public Builder address(String address) {this.address = address;return this;}public Person build() {return new Person(this);}}// getters, setters, toString, etc.
}

使用 Lombok,上面的所有建造者逻辑都会在编译时自动生成,你不需要手动编写这些代码。Lombok 会创建一个与上述手动实现的 Builder 类类似的内部类,并提供同样的链式调用功能。

在这里插入图片描述


四、建造者模式的注意事项

  1. 避免滥用建造者模式:虽然建造者模式可以提供一种清晰和灵活的方式来构建复杂对象,但过度使用它可能会导致代码变得复杂和难以维护。因此,在决定使用建造者模式之前,应该仔细评估对象的复杂性和构建过程的需求。

  2. 考虑建造者的可重用性:如果对象的构建过程涉及一些可重用的步骤或组件,那么可以设计可重用的建造者类来减少代码重复和提高可维护性。例如,可以创建一些通用的建造者类来处理常见的构建步骤,并在需要时进行扩展或定制。

  3. 注意与工厂模式的区别:建造者模式与工厂模式都是创建型设计模式,但它们的职责和用途有所不同。工厂模式主要负责对象的创建和实例化,而建造者模式则关注于对象的构建过程和属性的设置。在实际应用中,可以根据需要选择使用哪种模式或结合使用它们。

五、结语

  • 建造者模式是一种强大且灵活的设计模式,适用于构建具有多个属性和复杂构建过程的对象。
  • 通过合理使用建造者模式,可以提高代码的可读性、可维护性和可扩展性。
  • 然而,在使用建造者模式时,也需要注意避免滥用、考虑线程安全问题以及与其他设计模式的区别和协作。
  • 只有在合适的场景下使用建造者模式,才能充分发挥其优势并提升软件的质量。

经典建造者模式和流式建造者模式都是用于封装复杂对象创建过程的有效方式。经典建造者模式通过抽象建造者接口和具体建造者类的分离,实现了构建过程的灵活性和可扩展性。而流式建造者模式则通过链式调用的方式,提高了代码的可读性和编写的便捷性。

在选择使用哪种建造者模式时,需要根据具体的需求和场景来判断。如果需要较高的灵活性和可扩展性,可以考虑使用经典建造者模式;如果追求代码的简洁和易读性,流式建造者模式可能是一个更好的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/270526.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十:套接字和标准I/O,以及分离I/O流

1 标准I/O函数的优点 C语言标准IO整理 1.1 标准I/O函数的两个优点 标准I/O函数具有良好的移植性。 标准I/O函数可以利用缓冲提高性能 从图中可以看出,使用标准I/O函数传输数据时,经过两个缓冲。例如,使用fputs函数传输字符串 “Hello” 时…

安卓游戏开发之图形渲染技术优劣分析

一、引言 随着移动设备的普及和性能的提升,安卓游戏开发已经成为一个热门领域。在安卓游戏开发中,图形渲染技术是关键的一环。本文将对安卓游戏开发中常用的图形渲染技术进行分析,比较它们的优劣,并探讨它们在不同应用场景下的适用…

关于 selinux 规则

1. 查看selinux状态 SELinux的状态: enforcing:强制,每个受限的进程都必然受限 permissive:允许,每个受限的进程违规操作不会被禁止,但会被记录于审计日志 disabled:禁用 相关命令&#xf…

manjaro 安装 wps 教程

内核: Linux 6.6.16.2 wps-office版本: 11.10.11719-1 本文仅作为参考使用, 如果以上版本差别较大不建议参考 安装wps主体 yay -S wps-office 安装wps字体 (如果下载未成功看下面的方法) yay -S ttf-waps-fonts 安装wps中文语言 yay …

upload-Labs靶场“11-15”关通关教程

君衍. 一、第十一关 %00截断GET上传1、源码分析2、%00截断GET上传 二、第十二关 %00截断POST上传1、源码分析2、%00截断POST上传 三、第十三关 文件头检测绕过1、源码分析2、文件头检测绕过 四、第十四关 图片检测绕过上传1、源码分析2、图片马绕过上传 五、第十五关 图片检测绕…

mysql学习笔记8——常用5个内置方法

1count 对查询内容进行计数,并返回结果 2as as可以将查询出来结果赋予新名字 3sum sum可以查询某字段特定条件下的和值 4concat concat可以将多列数据合并成一列,只要concat()即可 5group_concat group_concat可以把多列…

Docker的镜像操作

目录 镜像的操作(**开头为常用请留意) 镜像查找 **拉取镜像 **推送镜像 **查看镜像 **修改镜像名称 **查看镜像的详细信息 ​编辑 删除镜像 查看所有镜像ID 删除全部镜像 **查看镜像的操作历史 镜像迁移 镜像打包 远程发送镜像(需要先打包) 本地镜像tar包恢复 镜像过…

【YOLO v5 v7 v8 v9小目标改进】辅助超推理SAHI:分而治之,解决高分辨率图像中小物体检测的问题

辅助超推理SAHI:分而治之,解决高分辨率图像中小物体检测的问题 设计思路结构小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改YOLO v9 魔改 论文:https://arxiv.org/pdf/2202.06934.pdf 代码:https://github.com/obss/sahi 设计思…

文件MD5校验码的安全性及重要性

title: 文件MD5校验码的安全性及重要性 date: 2024/3/6 18:13:20 updated: 2024/3/6 18:13:20 tags: MD5原理文件校验下载验证数据库一致性安全性保障计算方法MD5安全防护 文件MD5(Message Digest Algorithm 5)是一种常用的哈希算法,用于验证…

基于OpenCV的图形分析辨认04

目录 一、前言 二、实验目的 三、实验内容 四、实验过程 一、前言 编程语言:Python,编程软件:vscode或pycharm,必备的第三方库:OpenCV,numpy,matplotlib,os等等。 关于OpenCV&…

SqlServer中连续号及断号查询—附源码

效果如下图所示: SqlServer中连续号及断号查询SQL如下: --1.定义临时表 DECLARE TestTemp TABLE(TestCode NVARCHAR(50),TestNum INT )DECLARE DataTemp TABLE(TestCode NVARCHAR(50),TestNumStr NVARCHAR(100) )--2.插入测试数据 INSERT INTO TestT…

C及C++每日练习(1)

一.选择&#xff1a; 1.以下for循环的执行次数是&#xff08;&#xff09; for(int x 0, y 0; (y 123) && (x < 4); x); A.是无限循环 B.循环次数不定 C.4次 D.3次 对于循环&#xff0c;其组成部分可以四个部分&#xff1a; for(初始化;循环进行条件;调整) …

基于Java的校园失物招领管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 招领管理模块2.2 寻物管理模块2.3 系统公告模块2.4 感谢留言模块 三、界面展示3.1 登录注册3.2 招领模块3.3 寻物模块3.4 公告模块3.5 感谢留言模块3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 校园失物招领…

Cyber RT 开发工具

在Cyber RT中还提供了一些工具&#xff0c;这些工具可以拓展Cyber RT功能、提高开发调试效率&#xff0c;本章主要介绍这些工具的使用。 本章内容: 1.cyber record工具的应用&#xff1b; 2.常用命令工具的使用&#xff1b; 学习收获: 1.可以通过cyber record将发布的话题消息…

因果学习篇(2)-Causal Attention for Vision-Language Tasks(文献阅读)

Causal Attention for Vision-Language Tasks 引言 这篇论文是南洋理工大学和澳大利亚莫纳什大学联合发表自2021年的CVPR顶会上的一篇文献&#xff0c;在当前流行的注意力机制中增加了因果推理算法&#xff0c;提出了一种新的注意力机制&#xff1a;因果注意力(CATT)&#xff…

AI智商排名:Claude-3首次突破100

用挪威门萨&#xff08;智商测试题&#xff09;中 35 个问题对chatGPT等人工智能进行了测试&#xff1a; ChatGPT 对ChatGPT进行了两次挪威门萨测试&#xff0c;在 35 个问题中&#xff0c;它平均答对了 13 个&#xff0c;智商估计为 85。 测试方法 每个人工智能都接受了两次…

2023第十届GIAC全球互联网架构大会:洞察未来互联网架构的革新与突破(附大会核心PPT下载)

随着互联网的迅猛发展&#xff0c;其底层架构的演进与革新成为了推动全球数字化进程的关键力量。2023年第十届GIAC全球互联网架构大会如期而至&#xff0c;汇聚了全球互联网架构领域的顶尖专家、学者、企业领袖和创新者&#xff0c;共同探讨和展望互联网架构的未来发展趋势。本…

RabbitMQ 基本介绍

RabbitMQ 基本介绍 消息模型 所有 MQ 产品从模型抽象上来说都是一样的过程&#xff1a; 消费者&#xff08;consumer&#xff09;订阅某个队列。生产者&#xff08;producer&#xff09;创建消息&#xff0c;然后发布到队列&#xff08;queue&#xff09;中&#xff0c;最后…

centos7安装maven离线安装

1、从官方网站下载maven文件包 官方下载网站&#xff1a;https://maven.apache.org/download.cgi 2、创建文件夹解压文件 将下载好的安装包&#xff0c;放到创建的目录下&#xff0c;并解压 a、创建/app/maven文件 mkdir /app/mavenb、解压文件 tar -zxvf apache-maven-…

C#使用whisper.net实现语音识别(语音转文本)

目录 介绍 效果 输出信息 项目 代码 下载 介绍 github地址&#xff1a;https://github.com/sandrohanea/whisper.net Whisper.net. Speech to text made simple using Whisper Models 模型下载地址&#xff1a;https://huggingface.co/sandrohanea/whisper.net/tree…