代码健康(6):消除 YAGNI 坏味道

乔梁 | 2021-03-06

消除 YAGNI 坏味道

软件开发的大部分成本是维护成本。减少维护成本的一个方法是:“只在当你真正需要它时,才去编写它”。也就是所谓的 “你不需要它( You Aren’t Gonna Need It )” (缩写为 YAGNI )设计原则

那么,如何定位那些不必要的代码?请跟着你的鼻子走!嗅出代码坏味道

代码坏味道是指一种代码模式,通常会暗示着某种设计缺陷。例如,“创建了一个基类或者接口,但却只有一个子类”。这很可能是写这段代码的人当时认为在后续的开发中有可能需要更多的子类。

正确的做法是,增量式的开发与设计:直到真正需要第二个子类时,再提取出一个父类或接口。

下面的 C++ 代码就有 YAGNI 坏味道:

当仅需要一个类就可以完成功能时,使用父子类只会增加维护者对这两个的理解成本,以及写文档和写测试的负担。

class Mammal { ...
           virtual Status Sleep(bool hibernate) = 0;
       };
class Human : public Mammal { ...
  virtual Status Sleep(bool hibernate) {
    age += hibernate ? kSevenMonths : kSevenHours;
    return OK;
  }
};

在上面的代码片断中, 我们要处理的情况是,即使所有的调用者传递的参数是 false 时,你要也关心 hibernatetrue 时的测试用例;另外,当 Sleep 函数返回一个 error 时,也要处理,尽管根本不会发生这种情况。这就导致根本不可能被执行的无用代码。

请消除这些坏味道,简化代码:

class Human { ...
  void Sleep() { age += kSevenHours; }
};

下面还有一些 YAGNI 坏味道:

  • 除了测试用例以外,代码根本不被执行(也就是无法到达的死代码)
  • 类被实现成了子类(有虚方法和/或 protected 类型的成员变量),但实际上根本没必要子类化。
  • publicprotected 的方法或成员变量本来是可以使用private。
  • 参数、变量, 或标志位总是相同的值。

庆幸的是, YAGNI 和其它代码坏味道通常很容易通过简单的实现模式来发现,并且很容易使用简单的重构手段消除.

你还在添加当前不会被用到的代码么?

相信我,你不会需要它的(YAGNI)