Chapter 3、代码的坏味道

3.1 Duplicated Code(重复代码)

坏味道行列中首当其冲的就是Duplicated Code。如果你在一个以上的地点看到相同的程序结构,那么可以肯定:设法将它们合而为一,程序会变得更换。

最单纯的重复代码就是“同一个类的两个函数含有相同的表达式”。另一种常见情况就是“两个互为兄弟的子类含有相同表达式”。如果两个毫不相关的类出现重复代码,应该考虑对其中一个使用Extract Class,将重复代码提炼到一个独立类中,然后在另一个类内使用这个新类。

3.2 Long Method(过长函数)

百分之九十九的场合里,要把函数变小,只需使用Extract Method。找到函数中适合集中在一起的部分,将它们提炼出来形成一个新函数。

3.3 Large Class(过大的类)

3.4 Long Parameter List(过长参数列)

3.5 Divergent Change(发散式变化)

我们希望软件能够容易被修改。一旦需要修改,我们希望能够跳到系统的某一点,只在该处做修改。

如果某个类经常因为不同原因在不同的方向上发生变化,Divergent Change就出现了。你应该找出某特定原因造成的所有变化,然后运用Extract Class将它们提炼到另一个类中。

3.6 Shotgun Surgery(散弹式修改)

Divergent Change是指“一个类受多种变化的影响”,Shotgun Surgery则是指“一个变化引发多个类相应修改”。这两种情况下你都会希望整理代码,使“外界变化”与“需要修改的类”趋于一一对应。

3.7 Feature Envy(依恋情结)

对象技术的全部要点在于:这是一种“将数据和对数据的操作行为包装在一起”的技术。有一种经典气味是:函数对某个类的兴趣高过对自己所处类的兴趣。无数次经验里,我们看到某个函数为了计算某个值,从另一个对象那儿调用几乎半打的取值函数。疗法显而易见:把这个函数移至另一个地点。

3.8 Data Clumps(数据泥团)

常常可以在很多地方看到相同的三四项数据:两个类中相同的字段、许多函数签名中相同的参数。这些总是绑在一起出现的数据真应该拥有属于它们自己的对象。首先请找出这些数据以字段形式出现的地方,运用Extract Class将它们提炼到一个对象中。然后将注意力转移到函数签名上,运用Introduce Parameter Object 或Preserve Whole Object为它减肥。

3.9 Primitive Obsession(基本类型偏执)

大多数编程环境都有两种数据:结构类型运行你将数据组织成有意义的形式;基本类型则是构成结构类型的积木块。结构总是带来一定的额外开销。它们可能戴表着数据库中的表,如果只为做一两件事儿创建结构类型也可能显得太麻烦。

3.10 Switch Statements(switch惊悚现身)

面向对象程序的一个最明显特征就是:少用switch(或case)语句。从本质上说,switch语句的问题在于重复。你常会发现同样的switch语句散步于不同地点。如果要为它添加一个新的case子句,就必须找到所有switch语句并修改它们。面向对象中的多态概念可为此带来优雅的解决办法。

大多数时候,一看到switch语句,就应该考虑以多态来替换它。问题是多态该出现在哪儿。

如果只是在单一函数中有些选择事例,且并不想改动它们,那么多态就有点杀鸡用牛刀了。这种情况下Replace Parameter with Explicit Methods是个不错的选择。如果你的选择条件之一是null,可以试试Introduce Null Object。

3.11 Parallel Inheritance Hierarchies(平行继承体系)

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

消除这种重复性的一般策略是:让一个继承体系的实例引用另一个继承提下的实例。如果再接再厉运用Move Method和Move Field,就可以将引用端的继承体系消弭于无形。

3.12 Lazy Class(冗缀类)

如果一个类的所得不值其身价,它就应该消失。

3.13 Speculative Generality(夸夸其谈未来性)

如果某个抽象类其实没有太大作用,请运用Collapse Hierarchy。不必要的委托可运用Inline Class除掉。如果函数的某些参数未被用上,可对它实施Remove Parameter。如果函数名称带有多余的抽象意味,应该对它实施Rename Method,让它现实一些。

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

某个实例变量仅为某种特定情况而设,这样的代码让人不易理解,因为你通常认为对象在所有时候都需要它的所有变量。

3.15 Message Chains(过渡耦合的消息链)

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

这时候你应该使用Hide Delegate。你可以在消息链的不同位置进行这种重构手法。

3.16 Middle Man(中间人)

对象的基本特征之一就是封装--对外部世界隐藏其内部细节。封装往往伴随着委托。

但是容易过度使用委托。你也许会看到某个类有一半的函数都委托给其他类,这就是过度委托。这时应该使用Remove Middle Man,直接和负责的对象打交道。

3.17 Inappropriate Intimacy(狎昵关系)

两个类过于亲密。

继承往往造成过度亲密,因为子类对超类的了解超过后者的主观愿望。

3.18 Alternative Class with Difference Interface (异曲同工的类)

如果两个函数做同一件事,却有着不一样的签名,请运用Rename Method根据他们的用途重新命名。

3.19 Incomplete Library Class(不完美的库类)

复用常被视为对象的终极目的。但是也经常被高估--大多数对象只要够用就好。

3.20 Data Class(纯稚的数据类)

3.21 Refused Bequest(被拒绝的遗赠)

如果子类复用了超类的行为(实现),却又不愿意支持超类的接口,Refused Bequest的坏味道就会变得浓烈。可运用Replace Inheritance with Delegation来达到目的。

3.22 Comments(过多的注释)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容