java中实体类常见的设计模式
实体类常见的设计模式
1. Set 链式编程
在实体类中实现链式调用通常是指让 setter 方法返回当前对象实例(this
),从而允许连续调用多个 setter 方法设置属性值。这种方式可以使代码更加简洁和直观。
例如实体类为:
public class Person {private String name;private int age;public Person setName(String name) {this.name = name;return this; // 返回当前实例以支持链式调用}public Person setAge(int age) {this.age = age;return this;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + '}';}
}
使用:
Person person = new Person().setName("John").setAge(30);
System.out.println(person);
这种方式非常适合那些属性不是很多,或者不强制要求所有属性都必须初始化的情况。
可以使用
@Accessors(chain = true)
注解来自动启用链式调用(使用方式在后面)。
2. 构建者设计模式
当一个类有很多属性,特别是有些是可选的时候,使用传统的构造函数或链式 setter 方法可能会导致代码冗长且不易维护。构建者设计模式通过分离对象的构造过程与表示来解决这个问题,使得创建复杂对象的过程更加清晰和灵活。
例如实体类为:
public class Person {private final String name;private final int age;// 私有构造函数,防止直接实例化private Person(Builder builder) {this.name = builder.name;this.age = builder.age;}public static class Builder {private String name;private int age;public Builder name(String name) {this.name = name;return this; // 返回当前 Builder 实例以支持链式调用}public Builder age(int age) {this.age = age;return this;}public Person build() {return new Person(this); // 使用 Builder 中的数据创建新的 Person 实例}}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + '}';}
}
使用:
Person person = new Person.Builder().name("John").age(30).build();
System.out.println(person);
构建者模式特别适用于需要构建的对象具有许多可选参数的情况。它不仅提高了代码的可读性,也避免了构造函数参数列表过长的问题。
可以使用
@Builder
注解可以轻松实现构建者模式(使用方式在后面)。
3. 其它
3.1 两者与 Lombok 一同使用的问题
Lombok 是一个非常流行的 Java 库,它通过注解来减少样板代码,例如 getter、setter、构造函数等。然而,当你在同一个类中同时使用 Lombok 注解与手动实现的 Set 链式编程或构建者设计模式时,可能会遇到一些问题或冲突。
-
Set 链式编程与 Lombok
如果你使用 Lombok 的
@Setter
注解,并尝试手动实现链式 setter 方法,可能会出现以下问题:- 方法重复
- 不可预期的行为
为了解决这个问题,你可以选择不使用 Lombok 的
@Setter
注解,而是完全手动编写所有需要的 setter 方法,或者利用 Lombok 的@Accessors(chain = true)
注解来自动启用链式调用。例如:@Getter @Setter @Accessors(chain = true) public class Person {private String name;private int age; }
-
构建者设计模式与 Lombok
Lombok 提供了对构建者模式的支持,通过
@Builder
注解可以轻松实现构建者模式,避免手动编写复杂的 Builder 类。但是,如果同时手动实现构建者模式和使用 Lombok 的@Builder
注解,则可能会遇到类似的问题:- 代码冗余
- 冲突
为了避免这种情况,你应该选择一种方式来实现构建者模式。如果你希望利用 Lombok 简化代码,可以删除手动编写的 Builder 实现,转而使用 Lombok 的
@Builder
注解:@Getter @Builder public class Person {private final String name;private final int age; }
总之,在结合使用 Lombok 与自定义的 Set 链式编程或构建者设计模式时,关键是保持一致性并理解 Lombok 在背后所做的工作。通常情况下,推荐充分利用 Lombok 提供的相关注解来简化这些模式的实现,除非有特定的需求要求手动控制。这样做不仅可以减少出错的机会,还能让代码更加简洁易读。
3.2 又想方便编程、又想使用 Lombok 怎么做
-
使用
@Accessors(chain = true)
和其他 Lombok 注解当你想为你的实体类启用链式 setter 方法同时又希望自动生成
toString
、equals
和hashCode
方法时,你可以这样做:@Getter @Setter @Accessors(chain = true) @ToString @EqualsAndHashCode public class Person {private String name;private int age; }
在这个例子中,
@Getter
和@Setter
自动生成所有属性的 getter 和 setter 方法,@Accessors(chain = true)
使得 setter 方法支持链式调用。@ToString
自动生成toString
方法,而@EqualsAndHashCode
自动生成equals
和hashCode
方法。 -
使用
@Builder
和其他 Lombok 注解如果你想使用构建者模式(通过
@Builder
注解),同时还需要toString
、equals
和hashCode
方法,同样可以直接将这些注解添加到你的类上:@Getter // 注意:通常与 @Builder 一起使用时不需要 @Setter,除非你确实需要setter方法 @Builder @ToString @EqualsAndHashCode public class Person {private String name;private int age; }
这里需要注意的是,通常当你使用
@Builder
时,你可能不会为所有字段提供 setter 方法(因为 Builder 模式本身提供了设置属性值的方法)。然而,如果你确实需要 setter 方法,你可以继续使用@Setter
注解。
3.3 总结
虽然使用了 Set 链式编程、构建者设计模式 能更方便快捷的实现一个类,但是也产生了与 Lombok 之间的冲突,导致不能直接使用类似 @Data
等注解生成一些方法,但这个问题总的来说,是可以忽略的。
毕竟鱼和熊掌不可兼得,合适的场景使用合适的方法即可。
相关文章:
java中实体类常见的设计模式
实体类常见的设计模式 1. Set 链式编程 在实体类中实现链式调用通常是指让 setter 方法返回当前对象实例(this),从而允许连续调用多个 setter 方法设置属性值。这种方式可以使代码更加简洁和直观。 例如实体类为: public clas…...

【够用就好006】如何从零开发游戏上架steam面向AI编程的godot独立游戏制作实录001流程
记录工作实践 这是全新的系列,一直有个游戏制作梦 感谢AI时代,让这一切变得可行 长欢迎共同见证,期更新,欢迎保持关注,待到游戏上架那一天,一起玩 面向AI编程的godot独立游戏制作流程实录001 本期是第…...

发行思考:全球热销榜的频繁变动
几点杂感: 1、单机游戏销量与在线人数的衰退是剧烈的,有明显的周期性,而在线游戏则稳定很多。 如去年的某明星游戏,最高200多万在线,如今在线人数是48名,3万多。 而近期热门的是MH,在线人数8…...
docker目录挂载与卷映射的区别
在 Docker 中,目录挂载(Bind Mount)和卷映射(Volume Mount)的命令语法差异主要体现在路径格式上,具体表现为是否以斜杠(/)开头。以下是两者的核心区别及使用场景的总结: …...
`label` 标签的 `for` 属性详解
一、基本概念 label 标签的 for 属性用于将标签与表单控件(如 input、select 等)绑定,其值需与目标元素的 id 完全匹配。这种关联允许用户点击标签时触发控件交互(如聚焦输入框或切换复选框),提升操作便捷…...
公开笔记:自然语言处理(NLP)中文文本预处理主流方法
在自然语言处理(NLP)领域,将中文文本转化为数字的主流方法主要集中在预训练语言模型和子词编码技术上。这些方法能够更好地捕捉语义信息,并且在各种NLP任务中表现出色。以下是目前主流的文本编码方法: 1. 基于预训练语…...

【一个月备战蓝桥算法】递归与递推
字典序 在刷题和计算机科学领域,字典序(Lexicographical order)也称为词典序、字典顺序、字母序,是一种对序列元素进行排序的方式,它模仿了字典中单词的排序规则。下面从不同的数据类型来详细解释字典序: …...
算法策略深度解析与实战应用
一、算法策略的本质与价值 算法策略是计算机科学的灵魂,它决定了问题解决的效率与质量。优秀的算法设计者就像战场上的指挥官,需要根据地形(问题特征)选择最佳战术(算法策略)。本文将深入剖析五大核心算法…...

【LeetCode 热题 100】3. 无重复字符的最长子串 | python 【中等】
美美超过管解 题目: 3. 无重复字符的最长子串 给定一个字符串 s ,请你找出其中不含有重复字符的 最长的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 注…...

计算机网络(1) 网络通信基础,协议介绍,通信框架
网络结构模式 C/S-----客户端和服务器 B/S -----浏览器服务器 MAC地址 每一个网卡都拥有独一无二的48位串行号,也即MAC地址,也叫做物理地址、硬件地址或者是局域网地址 MAC地址表示为12个16进制数 如00-16-EA-AE-3C-40 (每一个数可以用四个…...
在 Docker 中,无法直接将外部多个端口映射到容器内部的同一个端口
Docker 的端口映射是一对一的,即一个外部端口只能映射到容器内部的一个端口。 1. 为什么不能多对一映射? 端口冲突: 如果外部多个端口映射到容器内部的同一个端口,Docker 无法区分外部请求应该转发到哪个内部端口,会…...

计算机网络开发(2)TCP\UDP区别、TCP通信框架、服务端客户端通信实例
TCP与UDP区别 UDP:用户数据报协议,面向无连接,可以单播,多播,广播, 面向数据报,不可靠TCP:传输控制协议,面向连接的,可靠的,基于字节流ÿ…...

ubuntu打包 qt 程序,不用每次都用linuxdeployqt打包
用linuxdeployqt打包太麻烦,每次程序编译都要用linuxdeployqt打包一次,而且每次都要很长时间,通过研究得出一个新的打包方法 1.用用linuxdeployqt得出依赖的库文件(只要没有增加新模块,只要用一次就可以) …...

【Python项目】基于深度学习的车辆特征分析系统
【Python项目】基于深度学习的车辆特征分析系统 技术简介:采用Python技术、MySQL数据库、卷积神经网络(CNN)等实现。 系统简介:该系统基于深度学习技术,特别是卷积神经网络(CNN),用…...
C++(初阶)(二)——类和对象
类和对象 类和对象类的定义格式访问限定符类域 实例化实例化概念内存对齐 this指针 类的定义 类(Class)是一种用于创建对象的蓝图或模板。它定义了对象(变量)的属性(数据)和方法(行为ÿ…...
JS—组成:2分钟掌握什么是ECMAScript操作,什么是DOM操作,什么是BOM操作
个人博客:haichenyi.com。感谢关注 1. 目录 1–目录2–组成3–内置对象 2. 组成 一直都在说JS,JS,到底啥是JS有了解过吗?JS由哪几部分组成的呢? 定义: JavaScript是一种轻量级、解释型或即时编译型的编程语…...

ArcGIS操作:10 投影坐标系转地理坐标系
应用情景:在计算shp面质心坐标的时,由于需要的坐标是经纬度,所以需要将投影坐标系转化为地理坐标系 1、打开工具箱 2、右侧:数据管理工具 → 投影和变换 → 要素 → 投影 3、选择投影的数据、输出路径、地理坐标系,点…...

NVIDIA Jetson Nano的国产替代,基于算能BM1684X+FPGA+AI算力盒子,支持deepseek边缘部署
NVIDIA Jetson Nano的国产替代,基于算能BM1684X的AI算力盒子,支持deepseek边缘部署 另外,还提供BM1684XFPGAAI的解决方案。 核心板基于Sophon SG2300X SoC(也叫BM1684X)打造 带有8核ARM Cortex-A53 2.3GHz,…...
c++全排列
题目描述 按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n。 输出格式 由 1∼n 组成的所有不重复的数字序列,每行一个序列。 每个数字保留 5 个场…...
VSCode 配置优化指南:打造极致高效的前端开发环境
VSCode 配置优化指南:打造极致高效的前端开发环境 一、基础环境配置:让开发更流畅 1. 性能优化设置 // settings.json {"files.autoSave": "afterDelay", // 自动保存(延迟1秒)"files.exclud…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...