Skip to content

Latest commit

 

History

History
148 lines (97 loc) · 4.73 KB

File metadata and controls

148 lines (97 loc) · 4.73 KB

重构哲学

Refactoring Philosophy

重构是手术不是修补——数学拓扑优先于编译器妥协。


§0 核心命题:框架是什么

框架是领域数学的固化。

框架不是"方便用户的工具集",而是强制性的数学结构——它规定了领域内概念的拓扑位置、依赖方向、暴露边界。正如欧几里得几何不会因为学生觉得难而修改公理,框架也不应该因为下游"已经在用"而保留泄露。


§1 为什么必须"不考虑下游"

下游是泄露的症状,不是资产

"不要考虑下游"听起来充满破坏性,但真正的原因是: 下游代码是框架泄露的灾难性结果——它们根本不应该被写出来。

如果为了"下游还在用"而妥协,就永远无法:

  • 从下游脱身
  • 学习如何将非特异性代码全部集中到框架能力中
  • 获得框架的自由抽象权力

破坏是治愈的前提

正如医生做手术不是为了伤害病人,而是为了治疗疾病:

  • 伤害代码不是为了破坏编译
  • 而是让顽固的代码疾病彻底治愈

医生不会在剪刀钳子和肿瘤还在患者肚子里的时候,就匆忙选择缝合伤口。

不会半途编译来假装没有错误。在手术中:

  • 唯一需要检查的是生命体征平稳(核心模块能否编译)
  • 而不是肚子上有没有洞(下游是否编译通过)

§2 重构原则

1. 数学拓扑优先于编译器妥协

不是在遵从编译器工作,而是在遵从数学拓扑结构工作。

推翻旧结构时必然遭到编译器的阻拦,但那是因为编译器愚蠢而不理解数学——它只是忠诚地不让我们破坏结构。

考虑问题的顺序

  1. 框架对纯粹领域内数学拓扑的固定和强制力
  2. 去掉任何不必要的公开可见性
  3. 去掉任何逻辑上有更优解而不必存在的代码
  4. 最后才考虑编译

2. 禁止重导出

公理:重导出几乎是自己承认"代码命名空间分布违背数学拓扑"。

如果概念 X 需要从 deep::path::X 重导出到 shallow::X,那么 X 从一开始就应该定义在 shallow 层。

执行

  • 在哪个命名空间,就去哪个命名空间使用
  • 不期望表层导出
  • 框架内部零重导出

3. Sugar 只在最外层

语法糖和便利重导出只应该在最最最表层提供给最外边的用户。

作为框架的核心开发者,给自己提供 sugar 毫无意义——我们本来就理解框架。

4. 不良依赖是扩散的癌症

在框架纯化完成之前:

  • 依赖不良抽象的下游视为扩散的癌症
  • 其代码死活与上游无关
  • 上游需要封闭地、自私地工作

§3 手术纪律

硬约束:大型重构必须在干净的 git 空间中进行

公理:大型重构是外科手术,不是门诊输液。手术需要无菌环境。

执行规则

  1. 安全同步点:在开始重构前,确保所有测试通过并提交一个干净的 commit。这是手术的"麻醉前检查"。
  2. 原子性:一次重构只做一件事。可以是大件事,但必须是一件事。
  3. 隔离:重构期间不修复无关 bug,不添加无关功能。手术室里不处理感冒。
  4. 验证:重构完成后必须全量测试通过才能提交。这是手术的"术后检查"。
  5. 回滚能力:任何时刻都可以通过 git reset --hard 回到安全同步点。手术失败可以缝回去。

禁止半途编译

手术是完整的。在手术中:

  • Core 模块必须始终能编译(生命体征监测)
  • 下游编译错误是预期的、正确的(手术切口)
  • 不在手术中间休息、提交、或假装完成

手术记录

每次重构完成后记录:

  • 数学动机(为什么必须做)
  • 结构变更(做了什么)
  • 验证结果(测试全量通过)
  • 已知残留(如有)

§4 不良实现是负资产

公理

不良实现不是资产,是负资产。对依赖负资产的下游坚持兼容是错误的。

推论

  • 对不良实现做重构时不考虑向前或向后兼容性
  • 拒绝以兼容性为目的但本质是放任技术债务的设计
  • 追求最佳实现,彻底执行

兼容性的正当使用

兼容性仅在以下场景合理:

  • 良好实现之间的版本过渡
  • 公开稳定 API 的有计划演化
  • 有明确时间线的废弃路径

兼容性合理的场景:

  • 保护依赖泄露的下游代码
  • 拖延已知的设计缺陷修复
  • 害怕破坏编译

哲学总结

框架是领域数学的固化,不是便利工具的堆砌。

破坏下游是治愈泄露的必要代价。

我们遵从数学拓扑,不遵从编译器。

手术在干净的无菌环境中进行,有安全的回退点。