返回博客
技能详解2026-03-30· 10 分钟阅读

/dao:系统性清理代码复杂度的正确方式

代码复杂度是软件项目最隐蔽的成本。它不会触发报错,但会让每一次改动都比上一次慢一点。/dao 用三层分类 + 图谱验证,把复杂度清理变成可重复执行的系统性流程。

技术债务有一个特性:它不会让系统崩溃,只会让每次改动都比上一次稍微慢一点。等你意识到问题的时候,已经积累了几个月甚至几年的负担。

大多数团队对技术债的态度是「知道有,不知道在哪,不敢动」。/dao 要解决的是:让代码复杂度从「模糊的感知」变成「可量化、可定位、可系统性处理」的问题。

三层分类

代码复杂度不是一种问题,是三类问题,处理方式完全不同:

架构层(Architecture)

架构层的问题是最危险的,也是最不能自动处理的。这类问题需要人工决策:

  • 不必要的抽象层:一个接口只有一个实现,从未被替换,但为了「以后扩展」加了一层
  • 过度模块化:把一个简单功能拆成了 5 个只有 2-3 个函数的微模块
  • 过早泛化:实现了一个通用框架,但实际上只有一个使用场景
  • 过度设计的事件/配置系统:用发布-订阅模式处理只有两个固定参与方的交互

/dao 会识别这些模式,在面板上展示给你,并给出「保留/简化/重构」的建议,但不会自动执行。因为这类决策需要了解业务背景,AI 无法替代。

模块层(Module)

模块层的问题涉及模块边界的划分,也需要人工确认:

  • 单模块功能膨胀:一个模块的功能数量超过了它的语义边界
  • 职责不清:「utils」模块里放了认证逻辑、格式化、数据库操作
  • 跨模块重复逻辑:相似的功能在三个不同模块里各自实现了一遍
  • 耦合过重:模块 A 依赖了模块 B 的 15 个内部函数

同样展示面板,你选择哪些需要处理,/dao 按你的决策执行。

代码层(Code)

代码层的问题可以全自动处理,而且每一步都通过图谱验证:

  • 死代码:从未被调用的函数、类、变量。删除前先确认图谱中调用者为零。
  • 循环依赖:模块 A 导入模块 B,模块 B 导入模块 A。图谱直接显示循环路径,切断指定边。
  • 过碎的函数:一个函数只有 3 行,只被一个地方调用,合并回调用处。
  • 桶式重导出:多层 __init__.pyindex.ts 只是在转发导出,没有实际逻辑。

「图谱验证」是关键:/dao 不会盲目删除。删死代码前查图谱确认零调用者;切断循环依赖前确认切断后调用关系不受影响;合并函数前确认合并后扇入不变。每一步有依据,不会误操作。

工作流程

  1. 扫描代码库,计算 8 维度健康评分
  2. 识别问题,按架构/模块/代码三层分类
  3. 架构层和模块层:展示决策面板,等待人工确认
  4. 代码层:根据你的决策 + 自动识别的问题,批量修复
  5. 每步修复后图谱验证,确认无误
  6. 提交,输出健康度变化报告

真实数据:Manon 自身代码库的清理结果

Manon v1.1.2 版本,我们把 /dao 应用于自身代码库(93 文件,800+ 实体):

指标之前之后变化
代码健康度评分88/10097/100+9
死代码实体4729-38%
测试覆盖率32%61%+29pp(覆盖率因死代码减少而提升)

具体操作:

  • 17 个从未被调用的函数被移除(图谱确认零调用者)
  • 4 个单函数模块合并(扇入不变,模块数量减少)
  • 多层 __init__.py 间接层简化(导入路径缩短)
  • 2 个循环依赖切断(图谱标出循环路径,手动确认切断点)

测试覆盖率从 32% 到 61%,原因不是新写了测试,而是死代码被删掉了——之前覆盖率低,有一部分是因为测试套件在统计那些永远不会被执行的死函数。清掉死代码后,实际覆盖率的分母变小了,覆盖率自然提升。

什么时候跑 /dao

我们的建议是建立定期节律,而不是等到「感觉很乱了」再清理:

  • 每个功能完成后:新增的代码可能引入新的死函数或不必要的抽象,趁热打铁
  • 每个里程碑后:大版本发布前做一次完整扫描,保证交付的代码质量有据可查
  • 接手新项目时:快速了解代码库的健康状况,作为后续工作的基线

技术债的清理不是一次性的大工程,是持续的小手术。/dao 的设计就是为了让这件事从「半年一次的痛苦重构」变成「两周一次的轻松维护」。

想了解我们如何做软件开发?

我们把这套方法论用在每一个客户项目上。欢迎聊聊你的具体需求。

联系我们