首页/开发/代码质量与评审速查/坏味道:夸夸其谈通用性(Speculative Generality)
重构手法62 条

坏味道:夸夸其谈通用性(Speculative Generality)

为想象中的扩展预留的抽象(只有一个子类的基类、无人调用的参数、从未使用的钩子):先删或内联,等真实需求出现再加;YAGNI 是它的处方。

什么是夸夸其谈通用性

夸夸其谈的通用性指为想象中的扩展预留的抽象:只有一个实现的接口、只有一个子类的基类、没人传的参数、从未被调用的钩子方法。这类结构带来阅读与维护成本,却不解决任何现实问题。处方是先内联或删除,等第二个真实需求出现时再提取抽象。

基本信息

典型信号抽象只有单一实现、参数无人传、方法无人调用
处方内联类、折叠继承层次、删除无用代码
指导原则不为假想的未来设计
保留依据是否有真实调用方或明确排期
实际代价阅读时不得不理解一层并不存在的可能

典型使用场景

  • 为以后可能支持多种数据库抽出的接口只有一个实现
  • 框架基类里的钩子方法从未被覆写
  • 配置项从来没有被设置过,代码里却保留分支
  • 参数对象里一半字段在所有调用处都取同一个值
  • 抽象工厂加反射配置,最终只装配出一个产品族

清理动作

清理动作
// 只被一个类实现的接口:先内联,等第二个实现出现再提取
// 无人传的参数:删除,需要时再加
// 从未被覆写的钩子方法:删除,或写明预留意向与评审记录
// 提示:公共接口删除前必须做引用检索(含文档与外部调用方)

抽象该不该留

情况处理理由
只有一个实现且无排期内联或删除抽象只增加一层间接
已确认短期内会有第二个实现保留有明确时间点与负责人
对外暴露的扩展点先评估外部调用删除前必须做引用检索
判断标准:说得清什么时候会用到、谁负责,就保留;说不清就先删掉。需要时再加的成本,通常低于长期维护假想的成本。
删除对外暴露的接口或方法前必须做引用检索,范围包括仓库代码、文档示例与外部调用方,否则可能删掉别人的入口。

易错点

  • 把以后要用当保留理由:抽象长期无人验证,反而阻碍真实重构
  • 删除公共接口不做引用检索:误删外部调用入口,造成下游报错
  • 用抽象掩盖不确定性:迟迟不做决定,代码里堆满未验证的可能性
  • 反向极端:把已有两个实现的分支也内联回重复代码,改一次要改多处

数据来源与参考

  • 《重构》第 2 版 · 第 3 章(Speculative Generality)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌