云计算百科
云计算领域专业知识百科平台

接手两千行祖传代码:如何从“屎山”中拯救后端老项目

关键词:代码重构、JdbcTemplate、SQL 管理、Map 滥用、可维护性

去年接手了一个后端老项目,翻开其中一个业务方法时,我愣住了——一个方法居然写了差不多 2000 行,密密麻麻的 jdbcTemplate.queryForList、满屏的 Map<String, Object>、穿插着各种 put 和 get,连一行像样的注释都没有。更让人困惑的是,项目中同时存在原生 JdbcTemplate 写死 SQL 和 MyBatis Mapper 调用两种方式,风格混乱,阅读起来像是在破译密码。

今天我们就以这段代码为例,聊聊这种“祖传代码”的特点、缺点,以及如何逐步改进。

代码特点分析

方法过长

在这里插入图片描述

SQL 全写在 Java 代码中

String sql = "SELECT t1.* FROM mact_node t1 JOIN …";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, projNo);

这种方式把 SQL 硬编码在 Java 代码中,一旦 SQL 需要修改,必须重新编译部署。

返回值全用 Map<String, Object>

for(Map<String, Object> map : list) {
String node = map.get("MACT_NODE").toString();
int planLock = map.get("is_plan_lock") == null ? 0 : Integer.parseInt(...);
}

逻辑重复,代码冗余

同样的方法被反复调用,参数稍有不同,但逻辑结构几乎一致。

事务注解 + 长方法

一个方法做太多事,违背单一职责原则。

@Transactional(rollbackFor = Exception.class)
public boolean dataHandleDetail(...) throws Exception {
// 2000+ 行代码
}

混杂的数据访问方式

  • 一部分用 jdbcTemplate 直接执行 SQL
  • 另一部分用 mactPlanService.list() 调用 MyBatis Mapper
  • 风格不统一,维护成本高。

这种代码的主要缺点

缺点说明
可读性差 字段名、SQL 逻辑、业务逻辑混在一起,难以快速理解
可维护性低 SQL 修改需要改 Java 代码,无版本控制
类型不安全 map.get("字段") 容易拼写错误,编译期无法发现
难以复用 相似逻辑重复编写,修改时需多处同步
难以测试 方法过长,依赖数据库状态,单元测试困难
事务边界模糊 一个方法做太多事,事务可能过大或过长

改进重构方向

SQL 外置化,使用 MyBatis XML

优点:SQL 与 Java 代码解耦、支持动态 SQL、便于 SQL 版本管理

使用 DTO 或实体类代替 Map

优点:类型安全、IDE 自动提示、便于 Lombok 简化代码

拆分长方法,遵循单一职责

将方法按功能拆分为多个小方法:每个方法j尽量不超过 50 行,职责明确。

引入服务层与仓储层

Service 层:负责业务逻辑编排
Repository 层:负责数据访问(使用 MyBatis)

统一数据访问方式

使用 MyBatis,避免混用多种访问方式。

添加注释与文档

特别是复杂业务规则应添加清晰注释。

引入单元测试与集成测试

对拆分后的小方法编写单元测试,对整体流程编写集成测试。


总结

面对这种“祖传代码”,不要试图一次性全部重构。可以按以下步骤推进:

  • 先理解业务:搞清楚这些 SQL 和 Map 到底在做什么
  • 小步重构:每次只改一个小模块,比如先抽取一个 SQL 到 Mapper
  • 逐步替换:从频繁修改或 Bug 多的部分开始替换
  • 补充测试:每重构一个模块,补充相应测试
  • 重构不是一蹴而就的工程,而是持续优化的过程。每一点改进,都是对系统可维护性的投资。


    如果你也正在面对类似的“祖传代码”,欢迎在评论区分享你的经历和应对策略。让我们一起在代码的废墟上,重建秩序与清晰。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 接手两千行祖传代码:如何从“屎山”中拯救后端老项目
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!