重复代码(Duplicated Code)

如果你在一个以上的地方看到相同结构的程序结构,那么可以肯定:设法将它们合而为一,程序会变得更好。

过长函数(Long Method)

拥有短函数的对象会活得比较好、比较长。

过大的类(Large Class)

如果想利用单个类做太多事情,其内往往就会出现太多实例变量。一旦如此,Duplicated Code 也就接踵而至了。

过长参数列(Long Parameter List)

有了对象,你就不必把函数需要的所有东西都以函数传递给它了,只需要传给它足够的、让函数能从中获得自己需要的东西就行了。函数需要的东西多半可以从函数的宿主类中找到。

发散式变化(Divergent Change)

如果某个类经常因为不同的原因在不同的方向上发生变化,Divergent Change 就出现了。

违反了 SRP(单一职责)

霰弹式修改(Shotgun Surgery)

依恋情结(Feature Envy)

数据泥团(Data Clumps)

数据项就像小孩子,喜欢成群结队地待在一块儿。你常常可以在很多地方看到相同的三四个数据:两个类中相同的字段、很多函数签名中相同参数。这些总是绑在一起出现的数据真应该拥有属于它们自己的对象。

基本类型偏执(Primitive Obsession)

对象技术的新手通常不愿意在小任务上运用小对象——像是结合数值和币种的 money 类、由一个起始值和一个结束值组成的 rang、电话号码或邮政编码(ZIP)等的特殊字符串。

switch 惊悚现身(Switch Statements)

面向对象程序的一个最明显特征就是:少用 switch(或 case)语句。从本质上上说,switch 语句的问题在于重复。

平行继承体系(Paralled Inheritance Hierarchies)

Paralled Inheritance Hierarchies 其实是 Shotgun Surgery 的特殊情况。在这种情况下,每当你为某个类增加一个子类,必须也要另一个类相应增加一个子类。如果你发现某个继承体系的类名称前缀和另一个继承体系的类名称前缀完全相同,便是闻到了这种坏味道。

冗赘类(Lazy Class)

你所创建的每一个类,都得有人去理解它、维护它,这些工作都是要花钱的。如果一个类的所得不值得其身价,它就应该消失。

夸夸其谈未来性(Speculative Generality)

当有人说“噢,我想我们总有一天需要做这事”,并因而企图以各种各样的钩子和特殊情况来处理一些非必要的事情,这种味道就出现了。那么做的结果往往造成系统更难理解和维护。

令人迷惑的暂时字段(Temporary Field)

有时你会看到这样的对象:其内某个实例变更仅为某种特殊情况而设,这样的代码让人不易理解,因为你通常认为对象在所有时候都需要它的所有变量。在变量未被使用的情况下猜测当初其设置的目的,会让你发疯的。

过度耦合的消息链(Message Chains)

如果你看到用户向一个对象请求另外一个对象,然后再向后者请求另外一个对象,让后再请求另一个对象。。。这就是消息链。实际代码中你看到的可能是一长串 getThis() 或一长串零时变量。采取这种方式,意味客户代码将与查找过程中的导航结构紧密耦合。一旦对象间的关系发生任何变化,客户端就不能不做出相应修改。

中间人(Middle Man)

对象的基本特征之一就是封装——对外部世界隐藏其内部细节。

狎昵关系(Inappropriate Intimacy)

有时你会看到两个类过于亲密,花费太多时间去探索彼此的 private 成分。如果发生在两个“人”之间,我们不必做卫道士;但对于类,我们希望它们严守清规。

异曲同工的类(Alternative Classes with Defferent Interface)

如果两个函数做同一件事,却有着不同的签名。

不完美的类库(Incompleted Libray Class)

纯洁的数据类(Data Class)

所谓 Data Class 是指:它们拥有一些字段,以及用于访问(读写)这些字段的函数,除此之外一无长物。

被拒绝的馈赠(Refused Bequest)

子类应该继承超类的函数和数据。但如果它们不想或不需要继承,又该怎么办呢?它们得到所有礼物,却只从中挑选几样玩。

过多的注释(Comments)

你看到一段代码有着长长的注释。然后发现,应该代码很糟糕才会写这些注释。