Java数据聚合服务代码重构咨询:700行复杂服务如何提升可维护性
代码重构落地方案
核心重构思路
针对参数不统一、串行可跳过执行的场景,可以通过「上下文容器+统一执行接口+流程编排」的组合方案落地,完美适配管道、责任链不匹配的问题:
- 第一步:统一上下文容器,封装所有原始输入、中间结果、最终报告对象,解决各步骤参数签名不一致的问题
- 第二步:抽象统一采集处理器接口,定义执行判断和执行逻辑两个标准方法,所有采集步骤都实现该接口
- 第三步:拆分原有大服务类,每个采集逻辑拆成独立的处理器实现类,符合单一职责原则
- 第四步:实现串行编排器,按业务顺序注册所有处理器,遍历执行时先判断是否需要执行,再调用对应逻辑
代码实现示例
1. 定义上下文容器
// 采集上下文,统一承载所有需要用到的参数和中间结果 public class CollectContext { // 原始输入参数 private Long input1; // 各步骤中间结果 private FirstPart firstPart; private SecondPart secondPart; private ThirdPart thirdPart; // 最终生成的报告 private Report report; // 按需添加getter/setter public CollectContext(Long input1) { this.input1 = input1; this.report = new Report(); } }
2. 抽象统一采集处理器接口
public interface DataCollectHandler { // 判断当前步骤是否需要执行 default boolean shouldExecute(CollectContext context) { return true; // 默认都执行,有跳过需求的实现类重写即可 } // 执行当前步骤的采集逻辑 void execute(CollectContext context); }
3. 拆分各采集逻辑为独立处理器
举两个实现示例,其余采集逻辑同理拆分:
// 第一部分数据采集处理器 @Component // Spring环境可以加组件注解,非Spring直接new即可 public class FirstPartCollectHandler implements DataCollectHandler { @Override public void execute(CollectContext context) { // 原getFirstPart的业务逻辑,从DB/接口取数 FirstPart firstPart = xxx; context.setFirstPart(firstPart); context.getReport().setFirstPart(firstPart); } } // 第五部分数据采集处理器,只有满足条件才执行 @Component public class FifthPartCollectHandler implements DataCollectHandler { @Override public boolean shouldExecute(CollectContext context) { // 对应原代码的if判断条件 return context.getInput1() > context.getSecondPart().getInput3(); } @Override public void execute(CollectContext context) { // 原getFifthPart的业务逻辑 FifthPart fifthPart = xxx; context.getReport().setFifthPart(fifthPart); } } // 第六部分数据采集处理器,对应else分支 @Component public class SixthPartCollectHandler implements DataCollectHandler { @Override public boolean shouldExecute(CollectContext context) { return context.getInput1() <= context.getSecondPart().getInput3(); } @Override public void execute(CollectContext context) { // 原getSixthPart的业务逻辑 SixthPart sixthPart = xxx; context.getReport().setSixthPart(sixthPart); } }
4. 重构原DataCollector类,实现流程编排
@Service public class DataCollector { // 按业务执行顺序注入所有采集处理器,Spring环境直接按顺序注入列表,非Spring直接手动创建列表按顺序放 private final List<DataCollectHandler> collectHandlers; // 构造注入,顺序就是执行顺序:First->Second->Third->Fourth->Fifth->Sixth public DataCollector(List<DataCollectHandler> collectHandlers) { this.collectHandlers = collectHandlers; } public Report collect(Long input1) { CollectContext context = new CollectContext(input1); // 串行执行所有处理器 for (DataCollectHandler handler : collectHandlers) { if (handler.shouldExecute(context)) { handler.execute(context); } } return context.getReport(); } }
重构收益
- 解决原大类臃肿问题,每个处理器职责单一,代码行数控制在百行以内,易维护易排查问题
- 解决参数签名不统一问题,所有步骤都从上下文取数,不需要适配不同入参
- 流程与逻辑解耦,后续新增采集步骤只需要新增处理器实现类,调整注入顺序即可,不需要修改原有代码,符合开闭原则
- 支持任意步骤的执行条件自定义,灵活适配业务分支逻辑
- 方便单元测试,每个采集步骤可以单独编写测试用例,不需要依赖其他逻辑
内容的提问来源于stack exchange,提问作者mzaje18
相关产品推荐
相关产品推荐

