在Java中如何设计职责单一的类_Java类设计原则解析
发布时间 - 2026-02-02 00:00:00 点击率:次职责单一的类应只做一件可清晰定义、独立测试和修改的事;判断标准是类名替换为“负责……的类”后,所有public方法都自然属于该省略内容,且避免混用不同领域动词、私有方法中隐藏协作逻辑、构造函数中创建业务对象等破绽。
职责单一的类不是靠名字里带“Manager”“Helper”“Utils”来体现的,而是看它是否只做一件事,并且这件事能被清晰定义、独立测试、独立修改。
一个类该有多少个 public 方法才算单一职责?
没有固定数量,关键看这些方法是否服务于同一抽象层次的同一目标。比如 UserRepository 有 save()、findById()、deleteById() 是合理的——它们都围绕“持久化用户”这一职责;但如果它还包含 sendWelcomeEmail() 或 validatePasswordStrength(),就明显越界了。
- 判断标准:把类名换成“
负责……的类”,填空后所有 public 方法都应自然落在这个省略号里
- 常见破绽:方法名里混用不同领域动词(如既有
parseJson()又有logError()) - IDE 提示可辅助识别:IntelliJ 的 “Extract Class” 快捷键(Ctrl+T)常会建议拆分,说明当前类已有隐性职责分裂
如何识别并剥离“悄悄多出来的职责”?
这类职责往往藏在 private 方法或构造逻辑里,比如一个本该只做数据转换的 OrderDtoMapper,内部却调用了 PriceCalculator.calculate() 并直接 new 了一个 DiscountService。
- 检查构造函数和初始化块:是否创建了不该由它管理的协作对象
- 搜索
new关键字:如果新建的是业务类(非 DTO、Exception、Collection 等基础类型),大概率是职责入侵 - 看单元测试命名:如果一个测试类要 mock 三类不同服务(支付、通知、库存),说明被测类正在协调多个领域
为什么 @Service + @Component 不等于职责单一?
Spring 的注解只解决“交给容器管”,不解决“这个类该管什么”。很多 @Service 类实际承担了参数校验、DTO 转换、事务边界、重试逻辑、日志埋点五种职责,只是因为都在一个 @Transactional 方法里,看起来“很连贯”。
- 典型信号:方法体内出现
if (xxx == null) throw new IllegalArgumentException()—— 校验不该由 service 层兜底 - 更安全的做法:用 record 或构造函数强制校验(如
OrderId.of(String)),让非法状态根本构造不出来 - 事务控制粒度:一个 service 方法里调用三个外部 API 并统一回滚?不如拆成三个小事务 + 补偿逻辑,每个只专注一件事
真正难的不是写出单一职责的类,而是在需求变更时守住边界——比如运营要求“下单成功后自动发券”,最容易的改法是在 OrderService.create() 末尾加一行 voucherService.issue(),但这一行就让订单服务开始感知券系统了。
# word
# java
# js
# json
# app
# ai
# java类
# 为什么
# spring
# String
# NULL
# if
# 构造函数
# throw
# class
# public
# private
# Collection
# 对象
# ide
# issue
# 只做
# 是在
# 一件事
# 的是
# 这一
# 都在
# 多个
# 已有
# 又有
# 这件事
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
Laravel如何生成URL和重定向?(路由助手函数)
Laravel如何实现API速率限制?(Rate Limiting教程)
如何用西部建站助手快速创建专业网站?
香港服务器选型指南:免备案配置与高效建站方案解析
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
javascript如何操作浏览器历史记录_怎样实现无刷新导航
Laravel如何处理和验证JSON类型的数据库字段
详解Huffman编码算法之Java实现
JavaScript数据类型有哪些_如何准确判断一个变量的类型
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
如何在 React 中条件性地遍历数组并渲染元素
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
LinuxShell函数封装方法_脚本复用设计思路【教程】
网站制作企业,网站的banner和导航栏是指什么?
如何在IIS中新建站点并解决端口绑定冲突?
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
如何在宝塔面板创建新站点?
如何快速生成ASP一键建站模板并优化安全性?
如何在IIS中配置站点IP、端口及主机头?
Android Socket接口实现即时通讯实例代码
如何注册花生壳免费域名并搭建个人网站?
佛山网站制作系统,佛山企业变更地址网上办理步骤?
如何在服务器上三步完成建站并提升流量?
EditPlus中的正则表达式实战(6)
个人网站制作流程图片大全,个人网站如何注销?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
Laravel如何创建自定义中间件?(Middleware代码示例)
北京专业网站制作设计师招聘,北京白云观官方网站?
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
如何彻底删除建站之星生成的Banner?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
如何用免费手机建站系统零基础打造专业网站?
如何在IIS管理器中快速创建并配置网站?
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
html如何与html链接_实现多个HTML页面互相链接【互相】
潮流网站制作头像软件下载,适合母子的网名有哪些?
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
如何快速搭建高效服务器建站系统?
如何快速生成橙子建站落地页链接?
如何制作一个表白网站视频,关于勇敢表白的小标题?
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤


