
前言:
付清技术债务的方法, 大家应该都不陌生:
- 将多个函数、方法中可共享 (重复) 的代码, 抽象形成新的函数、方法。
- 参数化所抽象提取出的共享的函数、方法。
这样付清了多个函数、方法中重复代码的技术债务, 但却也引入了其他严重的问题:
- 当多个函数、方法分别是处理不同、差异颇大的业务逻辑时, 从这些函数、方法中所抽象产生的共享的函数、方法, 将会陷入复杂的业务逻辑判断的地狱当中。
- 当多个函数、方法是属于测试代码时, 把这些函数、方法中可共享 (重复) 的代码, 抽象形成新的函数、方法, 将会使得这些函数、方法丧失测试代码原本应具备的沟通、理解需求的作用。
所以, 是否应消除 “重复代码” ? 一直是个没有定论、没有标准答案的争议。
我们回归到付清技术债务的目的上重新的来思考:
- 付清技术债务只有一个目的: 提升产品开发的效率、质量。
也就是说, 付清技术债务是为了提升产品开发的效率、质量; 消除 “重复代码” 只是付清技术债务时, 会运用到的一个方法、手段、选项, 而不是唯一的指标、目的。
所以, 我们真正该去思考的问题应该是:
- 不消除重复代码, 却能提升产品开发效率、质量的方法是什么?
不消除重复代码:
开发人员当面对需求变更或需新增特性时, (非正式的统计) 往往会花费 70% – 90% 的开发时间, 去理解所需要变更的多个函数、方法。
所以, 当我们在探讨付清技术债务以提升产品开发效率、质量的方法时, 我们真正应该去解决的一个核心的问题是:
- 如何使得开发人员能快速、高效的理解所需变更的多个函数、方法? 也就是说, “缩短” 开发人员理解、查找所需变更的多个函数、方法的时间, 将能比 “消除重复代码” 更能提升产品开发的效率、质量。
如何使得开发人员能快速、高效的理解、查找所需变更的多个函数、方法?
格式塔心理学 (Gestalt psychology) 中的相近原则 (Proximity principle) 为我们提供了思路、方法。
格式塔心理学 (Gestalt psychology) 中的相近原则 (Proximity principle) 指的是:
人类的认知系统会将距离相近的各部分趋于组成整体。也就是说, 人类往往会将距离相近的多个、不同的个体, 视为单一的整体。请参考图一, 图二。


人类的认知系统会将距离相近的各部分趋于组成整体; 这是个十分关键的点, 关于开发人员去理解所要变更的多个函数、方法。
也就是说, 当我们能从开发人员提交代码行为的背后, 分析出那些函数、方法在开发人员提交代码时, 是都会同时发生变更的, 然后, 我们就将这些函数、方法都给 “搬” 到一块, 那开发人员的认知系统便会将这些函数、方法视为 “单一的整体”, 而使得开发人员能快速、高效的理解这些函数、方法, “缩短” 开发人员理解、查找所需变更的多个函数、方法的时间, 进而提升产品开发的效率、质量。

CODESCENE 是目前唯一支撑相近原则 (Proximity principle) 的工具。
如图四, CODESCENE 告诉我们:
函数 suspend_scheduler 与 stack_element_dump 在开发人员提交代码时, 都同时的会发生变更, 但在suspend_scheduler 与 stack_element_dump 之间却隔著 “81” 个其他的函数!
所以, 假如, 不将 suspend_scheduler 与 stack_element_dump 给 “搬” 到一块, 开发人员的认知系统在理解 suspend_scheduler 与 stack_element_dump 上, 毫无疑问的, 将会是件没效率且又容易犯错的事。

结论:
运用相近原则 (Proximity principle) 付清技术债务的方法, 无疑的是一个相当容易且风险最低的作法。尤其, 是在交付时程很紧凑的项目中, 使用相近原则 (Proximity principle), 可使我们能避免陷入复杂的业务逻辑判断的地狱中。同时, 也能使得开发的效率、质量获得提升。更重要的是, 相近原则 (Proximity principle) 使得日后需再重构时, 也变得更容易、更高效。
相关阅读:
产品中的 Hotspots: 基于配置库中代码所隐藏的开发者行为, 高效的提升产品的质量与开发的效率
高效、低成本的付清技术债务; 在 200,000 行代码的模块里, 找到最值得优先关注的 180 行代码
别再傻傻的写单元测试了; Hotspots 告诉我们单元测试的真相: 单元测试是负债? 还是资产?