方法过长本质是混杂多职责,应按变更原因(如校验规则、业务策略、第三方接口)拆分为独立方法,并通过UserRegistrationUseCase协调调用,确保各环节可单独测试与替换。

一个方法太长,本质是它在干多件事。拆分不是为了“看起来短”,而是让每段逻辑只响应一种变化原因——比如校验规则改了、通知渠道换了、数据库字段变了,这些都该各自独立,互不影响。
看方法里有没有不同类型的职责混在一起
典型信号:一段代码里同时出现参数检查、业务计算、外部调用、日志记录、异常处理。这些事的变更频率和责任人完全不同。
- 参数校验(如邮箱格式、密码长度)常随合规要求或前端交互调整
- 业务计算(如折扣率、积分折算)由运营策略驱动,频繁变动
- 外部调用(发邮件、调支付网关)依赖第三方接口,稳定性差、升级频繁
- 日志和事务控制属于横切关注点,不该污染核心逻辑
按“谁会因为什么理由改它”来划边界
别按动词(比如“保存”“发送”“校验”)机械拆,而要问:如果明天法务说邮箱校验必须加国际域名支持,哪些代码要动?如果营销部门临时加个“新用户送10元券”,哪些地方要改?答案不同的逻辑,就该分到不同方法里。
- 把校验逻辑抽成 validateUser(user),返回 ValidationResult 或抛特定异常(如 InvalidEmailException)
- 把密码加密、时间戳设置等数据准备动作封装为 enrichUser(user, request)
- 把查重逻辑(用户名/邮箱是否存在)单独提为 isUsernameAvailable(username) 和 isEmailAvailable(email)
- 入库操作交给 userRepository.save(user),不掺杂任何业务判断
- 通知发送走 notificationService.sendWelcomeEmail(user),与注册主流程解耦
拆完后怎么组织调用关系
不要把所有小方法堆在一个类里再写个“总控方法”——那只是把臃肿从函数挪到了类。应该引入轻量协调层:
立即学习“Java免费学习笔记(深入)”;
- 新建一个 UserRegistrationUseCase 类,构造函数只注入 Validator、Enricher、Repository、Notifier 四个明确角色
- 它的 execute(User user, HttpServletRequest request) 方法只做三件事:校验 → 补全 → 持久化 → 通知,中间无分支、无计算、无 if
- 每个被委托的方法都能单独单元测试,比如 mock 掉 Notifier 就能测注册主干是否成功
顺便避开几个常见坑
拆分容易,但细节决定成败:
- 别把校验方法写成 static 工具类——失去可替换性,没法针对测试场景注入宽松校验规则
- 避免新方法里直接 new 对象或硬编码字符串(比如 SQL 片段、邮箱模板),应通过参数或接口传入
- 如果拆出的方法仍超过 15 行或含嵌套 if,说明它内部还有职责没分离干净,继续往下挖
- 拆之前先补上单元测试,确保行为不变;拆之后每个方法都要有对应测试,覆盖边界情况


















