头图

重构推导手记二:模型落地四则——从定性标尺到工程边界

配套主文:《重构的隐形标尺:领域命名数量比与认知负担的正U模型》
主文链接:https://segmentfault.com/a/1190000047972477
上一篇手记:《重构推导手记一:从“命名数量”到R=D/N,我试错了四次才锁定X轴》:https://segmentfault.com/a/1190000047985851
作者:幽燕落雨(ID:kingysu)
2026年7月 · 天津

📌 本次修订核心说明

  1. 公式修正:原 R=D/N 调整为 R=f(D/N),增加映射函数 f。这一改动彻底规避了“量化认知负担”的伪精确陷阱,明确了模型作为定性标尺而非数学计算器的属性。
  2. 曲线常态:明确正U曲线左半段为人写代码的常态,右半段为机写代码的常态。我们日常维护的代码里,九成以上都属于左半段的信号荒漠状态——这不是统计报表的数字,而是我维护fcitx5、读各类项目代码摸出来的普遍规律:真正常规的、健康的代码反而是少数,大部分都在欠账里打转。
  3. 重构分层:基于上述常态,首次明确区分战术重构与战略重构,旨在厘清单次操作的短期成本与系统维护的长期收益之间的辩证关系。
  4. DDD绑定:将模型中的“领域命名(D)”严格锚定于DDD四层架构的领域层,其余三层命名计入非领域命名(N)。这为模型提供了坚实的架构学理支撑,避免了“领域”一词的泛化滥用。

⚠️ 适用范围与核心前提

本模型为定性框架,评估长期维护成本。允许单次重构短期Y升高,只要长期Y下降即为合法。绝大部分场景处于左半段信号荒漠,主流目标是长期增加D、减少无效N。


缘起:从系列一的试错到多态重构的隐性前提

系列一记录了从“命名数量”到“有效净值”、“抽象层级”,最终敲定R=D/N核心框架的四次试错。当时的推导已经明确模型是定性标尺、删除了数值刻度,但受限于初期直觉,我仍把它表达为线性等式的形式,还没意识到这种写法会隐含“量化认知负担”的伪精确陷阱——这个坑直到本次梳理工程规律时才填上。

核心动力始终是解决Fowler未言明的模糊性:比如他强调“坏名字是恶魔”,却没说清为什么有些改名反而更混乱。在研读《重构》第六章多态重构时,这种模糊性进一步具象化:Fowler说“单继承体系仅改父类转发方法”,却省略了“收回D的定义权”这一隐性前提。若子类存在override,父类转发层即为摆设。必须删掉所有子类override,将D的定义权唯一收归父类,才能消除冗余D,避免伪R陷阱。


公式修正:从 R=D/N 到 R=f(D/N)

系列一中的 R=D/N 仅为初期直觉表述,本次修订为 R=f(D/N),核心原因是线性等式完全无法表达重构的底层工程规律。

系列一我们反复验证过:正U曲线右半段的高认知负担,根源是辅助型 N 被过度Inline削除,而非 N 泛滥。比如订单价格计算逻辑:若有 discountedPrice 这个衔接变量,逻辑一目了然;若为了“短函数”将其Inline,拆成三个无关联的原子函数调用,读者就得自己拼凑逻辑。

更重要的是,加 f 就是为了彻底堵死“量化认知负担”的伪精确陷阱。之前有人看到 R=D/N,就琢磨“算个阈值,R 小于某个具体值就算甜区”,这完全背离了我们推导模型时“剔除数值刻度”的核心初衷。f(D/N) 明明白白告诉我们:这是定性标尺,不是计算器——它把“短期加转发层的成本、长期减少排查bug的收益”这些没法量化的工程权衡都装在映射逻辑里,我们只需要看趋势,不用算数值。


正U曲线的左右常态:人写vs机写

R=f(D/N) 的曲线分布不对称,左右成因截然不同。这也是系列一中AI误判右半段的根源所在。

左半段:人写代码的常态(绝大部分场景)

  • 成因:人类为赶进度、图省事,常产出信号荒漠代码——D严重不足(如 a / tmp),或N充斥噪音(如 Manager / Helper)。
  • 重构目标:长期增加D、减少无效N。比如把散落的全局变量收拢到统一的配置结构体中,把模糊的 a 提炼为 discountedPrice,短期需修改大量引用,长期则无需反推变量语义。
  • 注意:此阶段的合法重构必然伴随短期Y升高,这是必要的“入场费”,而非错误。

右半段:机写代码的常态(新兴风险)

  • 成因:AI为迎合Clean Code规范,过度Extract逻辑,同时Inline掉必要的辅助变量(如 discountedPrice),导致D碎片化、N被过度削减,形成“命名孤岛”。系列一中AI误判右半段为N泛滥,正是这种机写代码风险的典型体现。
  • 重构目标:恢复必要的辅助型N,合并冗余D。比如把AI拆分的原子函数重新内联,保留衔接变量。
  • 现状:目前占比不高,但随着AI生成代码普及,正在成为新的维护痛点。

重构分层:战术重构与战略重构

明确了代码的常态分布,我们便能厘清重构的层次。模型首次区分两类重构,以解决“短期Y升高是否合理”的争议。

1. 战术重构(小修小补,模型不重点关注)

  • 定义:针对单函数、单变量的局部调整,如重命名 a 为 discountedPrice。
  • 特征:短期仅改少量引用,Y小幅升高;长期Y小幅下降,收益有限。
  • 适用性:左半段日常的修修补补。无需模型严格评估,短期成本是微不足道的。

2. 战略重构(伤筋动骨,模型核心评估对象)

  • 定义:针对全局状态、公共API、大类拆分的系统性调整,如全局配置收拢、拆分巨型业务类、跨上下文接口迁移。
  • 特征:短期需修改数十甚至上百处引用,加转发层、适配兼容性,Y显著升高;长期Y大幅下降,避免系统性维护风险。
  • 适用性:对应左半段的大规模治理,或右半段的纠偏。必须严格评估长期收益——只要长期Y下降,短期成本就是必要的“入场费”。

与DDD的深度绑定:D就是领域层的命名

模型的“领域命名(D)”严格对应DDD四层架构中的领域层命名,其余三层命名全部计入非领域命名(N)。这一绑定彻底解决了命名边界模糊的问题,也呼应了系列一“D是核心业务信号”的初始定义。

DDD分层对应模型角色示例重构规则
领域层D(分子,核心业务信号)Order实体、Money值对象、领域服务等严禁冗余D,必须收回定义权;不可变值对象可直接暴露字段,无需封装。
应用层辅助型N(分母,必要衔接层)事务ID、跨上下文防腐层接口、父类转发方法允许存在,不得过度删除。
基础设施层辅助型N/噪音型NMapper、数据库连接池辅助型N需保留,噪音型N(如OrderManager)需删除。
用户界面层辅助型N(分母,适配层)VO对象、前端表单字段允许存在,不得混入领域语义。
非OOP场景的实证:编译期多态下的辅助型N
上述DDD分层规则并非只适用于面向对象的虚函数继承场景,在无继承关系的编译期多态中同样成立。典型的如C风格的回调函数指针:两个独立的功能单元(如不同硬件驱动的刷新函数)没有继承关系,却共享同名函数签名,必须通过转发层衔接。这类转发层属于应用层的辅助型N,对应DDD的防腐层逻辑——删除它会直接导致编译期绑定断裂,属于典型的「右侧误拆桥梁」。这也进一步验证了:只要是跨单元的衔接逻辑,无论是否有继承关系,辅助型N都不得过度删除。

实战心法:重构前四问

  1. 分层问:这是战术重构还是战略重构?战略重构才需用模型严格评估长期收益。
  2. 常态问:当前代码处于左半段(人写)还是右半段(机写)?左增D减无效N,右补辅助N合冗余D。
  3. DDD问:修改的是否属于领域层的D?是否混入了其他层的语义?避免将应用层的辅助命名误判为领域D。
  4. 成本问:短期增加的维护成本,是否能置换长期更大的模糊性负债?如全局配置收拢的短期修改成本,是否远低于未来排查“谁改了配置”的时间成本。

小结

系列一完成了模型的原点推导——敲定了 R=D/N 的核心框架,明确了定性标尺的属性;本篇则完成了模型的迭代修正:将 R=D/N 优化为 R=f(D/N),使其更准确地表达非线性映射关系。从公式修正出发,到曲线常态的划分,再到重构分层的策略,最后落脚于DDD的理论支撑,所有调整均源自对重构本质的思考。后续系列手记将进一步聚焦AI过度重构的识别标准,以及值对象场景的落地实践。


附录:原创声明

本文核心推导过程可与AI助手元宝2026年7月的对话记录相互印证,模型为作者独立推导。
版权协议:CC BY-NC 4.0(署名-非商业性使用),转载请注明作者及出处。


幽燕落雨
1 声望0 粉丝

幽燕落雨(kingysu),阅读过《代码大全》《重构》《Effective C++》《软件设计的哲学》《深入浅出设计模式》等多本经典书,对软件开发有一些自己的理解,偶尔给开源社区修修小bug