目录
10.Switch Statements(switch惊悚现身)
11.Parallel Inheritance Hierarchies(平等继承体系)
13.Speculative Generality(夸夸其谈未来性)
17.Inappropriate Intimacy(狎昵关系)
18.Alternative Classes with Different Interfaces(异曲同工的类)
19.Incomplete Library Class(不完美的程序类库)
1.Duplicated Code(重复的代码)
假设你在一个以上的地点看到同样的程序结构,那么当可肯定:设法将它们合而为一,程序会变得更好。
2.Long Method(过长方法)
针对过长的方法,我们需要进行分解,我们遵循这样一条原则:每当感觉须要写注释来说明代码的时候。我们就把须要说明的
东西写进一个独立的方法中,并以其意图(而非实现手法)命名。我们可以对一组甚至短短一行代码做这件事。哪怕替换后的方法
调用动作比方法自身还长,只要函数名称能够解释其用途,我们就应该毫不犹豫地那么做。关键不在于函数的长度,而在于函
数"做什么"和"如何做"之间的语义距离。
3.Large Class(过大的类)
说明这个类做太多事情。其内往往就会出现太多instance变量。一旦如此。Duplicated Code也就接踵而至了。
和"太多实例变量"一样,类内如果有太多代码,也是代码重复、混乱并最终走向死亡的源头。最简单的解决方案是把多余的东
西消弥于类内部。如果有五个"百行函数",它们之中很多代码都相同,那么或许你可以把它们变成五个"十行函数"和十个提炼
出来的"双行函数";还可以先确定客户端如何使用它们,运用抽象接口为每一种使用方式提炼一个接口。
4.Long Parameter List(过长參数列)
当一个方法有太长的参数时,会使得该参数列难以理解,太多参数会造成前后不一致、不易使用。可以将来自同一个对象的一
堆数据收集起来,并以该对象替换他们。如果某些数据缺乏合理的对象归属,可以制造一个对象参数。
5.Divergent Change(发散式变化)
我们希望软件可以更容易被改动——毕竟软件再怎么说本来就该是[软]的。一旦须要改动,我们希望可以找到系统的某一点,仅
仅在该处做改动。Divergent Change是指[一个class受多种变化的影响]。如果某个类经常因为不同的原因在不同的方向上发
生变化,那么此时将对象分成多个会更好,这么一来每个对象就可以只因一种变化而需要修改。
6.Shotgun Surgery(霰弹式修改)
Shotgun Surgery类似Divergent Change。但恰恰相反。假设每遇到某种变化,你都必须在很多不同的class内做出很多小改动
以响应之。你所面临的坏味道就是Shotgun Surgery。假设须要改动的代码散布四处。你不但非常难找到它们。也非常容易忘记
某个重要的改动。这种情况下你应该把所有需要修改的代码放进同一个类,如果眼下没有合适的类可以安置这些代码,就创造
一个。
Shotgun Surgery是指[一种变化引发多个classes对应改动]。
7.Feature Envy(依恋情结)
我们会看到某个方法为了计算某值,从另一个对象那儿调用差点儿一半以上取值方法。这样最好是将当前对象的方法移动至另
外一个对象,如果一个方法调用了多个类的多个功能,那么它究竟该被置于何处呢?我们的原则是:判断那一个类拥有最多调
用方法,然后就把这个函数和那些数据摆在一起。
最根本的原则是:将总是一起变化的东西放在一块儿。[数据和[引用这些数据]的行为总是一起变化的。
8.Data Clumps(数据泥团)
数据项就像小孩子,喜欢成群结队地待在一块儿。你经常能够在非常多地方看到同样的三或四个数据项:两个类中相同的
字段、很多方法签名中相同的参数。这些总是绑在一起出现的数据真应该放进属于它们自己的对象中。
9.Primitive Obsession(基本类型偏执)
大多数编程环境都有两种数据:结构类型让你将数据组织成有意义的形式;基本类型则是构成结构型别的积木块。
10.Switch Statements(switch惊悚现身)
面向对象程序的一个最明显特征就是:少用switch(或case)语句。从本质上说,switch语句的问题在于重复。大多数时候,一看
到switch语句,就应该考虑以多态来替换它,可以将switch语句提炼到一个独立函数中,再将它搬移到需要多态性的那个类
里。
11.Parallel Inheritance Hierarchies(平等继承体系)
Parallel Inheritance Hierarchies事实上是Shotgun Surgery的特殊情况。在这样的情况下。每当你为某个class添加一个
subclass,必须也为其它已实现的兄弟class对应添加一个subclass。消除这种重复性的一般策略是:让一个继承体系的实例引
用另一个继承体系的实例。
12.Lazy Class(冗赘类)
你所创建的每个class,都得有人去理解它、维护它,这些工作都是要花钱的。假设一个class的所得不值其身份。它就应该消
失。
13.Speculative Generality(夸夸其谈未来性)
这个令我们十分敏感的坏味道,命名者是Brian Foote。当有人说“噢,我想我们总有一天须要做这事”并因而企图以各式各样的
挂勾和特殊情况来处理一些非必要的事情,这样的坏味道就出现了。
14.Temporary Field(令人迷惑的临时字段)
有时你会看到这种对象:其内某个 instance 变量仅为某种特定情势而设。这种代码让人不易理解,由于你通常觉得对象在全部
时候都须要它的全部变量。在变量未被使用的情况下推測当初其设置目的,会让你发疯。可以单独抽出一个类来存储这些
instance 变量和这个变量相关的代码。
15.Message Chains(过度耦合的消息链)
假设你看到用户向一个对象索求还有一个对象,然后再向后者索求还有一个对象,然后再索求还有一个对象……这就是
Message Chain。实际代码中你看到的可能是一长串getThis()或一长串暂时变量。採取这样的方式,意味客户将与查找过程中
的航行结构紧密耦合。针对这种情况可以先观察消息链最终得到的对象是用来干什么的,看看是否可以把使用该对象的代码提
炼到一个方法,再把这个方法推入消息链。如果这条链上的某个对象有多位客户打算航行此航线的剩余部分,就加一个函数来
做这件事。
16.Middle Man(中间转手人)
人们可能过度运用delegation。你或许会看到某个class接口有一半的方法都托付给其他class,这样就可能是过度运用。这时应
该让方法和真正负责的对象打交道。
17.Inappropriate Intimacy(狎昵关系)
有时候你会看到两个classes过于亲热,花费太多时间去探究彼此的private成分。假设这发生在两个人之间。我们不必做卫道
之士;但对于classes,我们希望它们严守清规。继承往往造成过度亲热,由于subclass对superclass的了解总是超过
superclass的主观愿望。假设你认为该让这个孩子独自生活了,请运用Replace Inheritance with Delegation让它离开继承体
系。
18.Alternative Classes with Different Interfaces(异曲同工的类)
假设两个方法做同一件事,却有着不同的签名式,针对这种case应该根据他们的用途重新命名。
19.Incomplete Library Class(不完美的程序类库)
20.Data Class(纯稚的数据类)
所谓Data Class是指:它们拥有一些字段,以及用于訪问这些字段的方法,除此之外一无长物。
21.Refused Bequest(被拒绝的遗赠)
Subclasses应该继承superclass的方法和数据。但假设它们不想或不须要继承,又该怎么办呢?它们得到全部礼物。却仅仅从
中挑选几样来玩!按传统说法,这就意味继承体系设计错误。
22.Comments(过多的注释)
别操心,我们并非说你不该写注释。从嗅觉上说,Comments不是一种坏味道;其实它们还是一种香味呢。我们之所以要在这
里提到Comments,由于人们常把它当作除臭剂来使用。经常会有这种情况:你看到一段代码有着长长的注释。然后发现,这
些注释之所以存在乃是由于代码非常糟糕。这种情况的发生次数之多。实在令人惊讶。Comments能够带我们找到本章先前提
到的各种坏味道。