本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42041757

在重构入门篇中,简单地介绍了重构的定义、为何重构、何时重构等。我想对于重构是如何运作的,你已经有了较好的理解了。但是对于代码中的坏味道,你可能知道的并不多。坏味道可能是无形中产生的,也可能是开发人员偷懒造成的,还可能是其它某些因素导致的。不管怎么样,代码中的坏味道对程序没有半点好处,它会促使程序腐烂,甚至变质。对于开发人员,真的是很有必要对这些坏味道进行了解和熟悉,理解它们产生的场景。针对当前程序,发现坏味道,对代码进行重构,以消除坏味道,提高代码质量,提高自己水平。

下面让我们一起来熟悉和学习开发中经常出现的22种坏味道情形中的11种。其中,前四种坏味道在大多数开发过程中是不可避免的情形;后面若干种坏味道也会经常性地出现在程序中。我们应该发现它们的存在,并消除它们。

(1)重复的代码

重复的代码是坏味道中出现频率最高的情形非其莫属。如果在一个的以上地方看到相同的代码,那么就可以肯定:想办法将它们合而为一,代码会变得更好。最单纯的重复代码就是“同一个类的两个函数含有相同的表达式”,这时候可以采用抽取方法提炼出重复的代码,然后让这两个地点都调用被提炼出的那一段代码。

另一种常见情况就是“两个互为兄弟的子类内含相同的表达式”,这时候只需对两个类抽取方法,然后将提炼出的代码推入到超类中。如果代码之间只是类似而并非完全相同,那么就需要通过抽取方法将相似部分和差异部分分开,构成单独一个函数。如果有些函数以不同的算法做相同的事,可以使用比较清晰的一个替换掉其余的。

(2)过长的函数

程序员都喜欢简短的函数。拥有短函数的对象会活的比较好、比较长。不熟悉面向对象技术的人,常常觉得对象程序中只有无穷无尽的委托,根本没有进行任何计算。和此类程序共同生活数年后,你才会知道这些小小函数的价值。

应该积极地分解函数,将长长的函数变为多个短小的函数。一般会遵循这样的原则:每当感觉需要用注释来说明点什么的时候,就把需要说明的东西写进一个独立函数中,并以其用途命名。不要嫌麻烦。可以对一组甚至短短一行代码做这件事,哪怕替换后的函数调用动作比函数自身还长,只要函数名称能够解释其用途,也应毫不犹豫地那么做。关键不在于函数的长度,而在于函数“做什么”和“如何做”之间的语义距离。


(3)过大的类

如果想利用单个的类做太多的事情,其内往往会出现太多实例变量。一旦如此,重复的代码就接踵而来。

可以将几个变量一起提炼至新类内。提炼时应该选择类内彼此相关的变量,将它们放在一起。通常如果类内的数个变量有着相同的前缀或字尾,这就意味有机会把它们提炼到某个组件内。

和“太多实例变量”一样,类内如果有太多代码,也是代码重复、混乱并最终走向死亡的源头。最简单的方案是把多余的东西消弭于类内部。如果有五个“百行函数”,它们之中很多代码都相同,那么或许你可以把它们变成五个“十行函数”和十个提炼出的“双行函数”。


(4)过长的参数列

刚开始学编程的时候,或许都是“把函数所需的所有东西都以参数传递进去”。这样也是可以理解的,因为除此之外就只能选择全局数据,而全局数据是邪恶的东西。对象技术告诉我们,如果你手上没有所需的东西,总可以叫一个对象给你。有了对象,你就不必要把函数所需的所有东西都以参数传递给它,只需传给它足够的、让函数能从中获得自己的东西就行。

太长的的参数列难以理解,太多参数会造成前后不一致、不易使用,而且一旦需要更多数据,就不得不修改它。如果将对象传递给函数,大多数修改都将没有必要,因为很可能只需增加一两条请求,就能得到更多的数据。

(5)发散式变化

我们希望软件能够容易被修改——毕竟软件再怎么说本来就该是“软”的。一旦需要修改,我们希望能够跳到系统某一点,只在该处做修改。如果不能做到这点,你就会嗅出两种紧密相关的刺鼻味道中的一种。

如果某个类经常因为不同的原因在不同的方向上发生变化,发散式变化就出现了。其主要指“一个类受多种变化的影响”。当你看着一个类说:“呃,如果新加入一个数据库,就必须修改这三个函数;如果新出现一种工具,就必须修改这四个函数。”那么此时也许将这个对象分成两个会更好,这样对每个对象就可以只因一种变化而需要修改。

(6)霾弹式修改

如果每遇到变化,都必须在许多不同的类内做出许多小修改,你所面临的坏味道就是霾弹式修改。其主要指“一种变化引发多个类相应修改”。如果需要修改的代码散布四周,不但很难找到它们,也很容易忘记某个重要的修改。

这种情况可以把所有需要的代码放进同一个类。如果眼下没有合适的类可以安置这些代码,就创造一个。通常可以运用内联类把一系列相关行为放进同一个类。


(7)依恋情节

众所周知,对象技术的全部要点在于:其是一种“将数据和对数据的操作行为包装在一起”的技术。有一种经典的气味:函数对于某个类的兴趣高过对自己所处类的兴趣。在很多情况下,都能够看到:某个函数为了计算某个值,从另一个对象那儿调用几乎半打的取值函数。疗法也显而易见:把这个函数移至另一个地点,移到它该去的地方。‘

有时候一个函数往往会用到几个类的功能,那么它究竟该被置于何处呢?处理原则通常为:判断哪个类拥有最多被此函数使用的数据,然后就把这个函数和那些数据摆在一起。

(8)数据泥团

如果用比较形象的事物来形容数据项,我想“小孩子”是一个不错的选择,数据项就像小孩子,喜欢成群结队地呆在一块儿。常常可以在很多地方看到相同的三四项数据:两个类中相同的字段、许多函数签名中相同的参数。这些总是绑在一起出现的数据真应该拥有属于它们自己的对象。

这种情况可以先找出这些数据以字段形式出现的地方,将它们提炼到一个独立对象中,然后将注意力转移到函数签名上,运用参数对象为它减肥。这样做的直接好处是可以将很多参数列缩短,简化函数调用。一个比较好的评判方法是:删掉众多数据中的一项。这么做其它数据有没有因而失去意义?如果它们不再有意义,这就是一个明确的信号:应该为它们产生一个新对象。

(9)基本类型偏执

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

对象的一个极大价值在于:它们模糊甚至打破横亘于基本数据和体积较大的类之间的界限。如果你有一组应该总是被放在一起的字段,可以将其抽取为一个独立的类。如果你在参数列中看到基本型数据,可以引入参数对象进行处理。如果你发现自己正从数组中挑选数据,可以运用以对象取代数组进行处理。

(10)Switch惊悚现身

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

大多数时候,一看到switch语句,那就应该考虑以多态来替换它。switch语句常常根据类型码进行选择,你要的是“与该类型码相关的函数或类”,所以应该将switch语句提炼到一个独立函数中,再将它搬移到需要多态性的那个类里。

(11)平行继承体系

平行继承体系其实是霾弹式修改的特殊情况。在这种情况下,每当为某个类增加一个子类,必须也为另一个类增加一个子类。如果发现某个继承体系的类名称前缀和另一个继承体系的类名称前缀完全相同,这种坏味道就会被嗅出。

消除这种重复性的一般策略是:让一个继承体系的实例引用另一个继承体系的实例。

本文简单介绍了22种代码坏味道中的11种,通过对这些坏味道的了解,促使我们在开发过程中,经常性地思考自己所写代码中是否存有坏味道,一旦发现坏味道,就应该着手进行重构,而不是看着代码慢慢腐烂。如果你能坚持完整地看完本文,我想你肯定也会坚持经常性地清理代码中坏味道,提高代码的质量,提高自己的水平。

希望本文对你有所帮助。有问题可以一起交流、讨论。

重构笔记之前文章如下:

重构笔记——入门篇

重构笔记——代码的坏味道(上)相关推荐

  1. 【重构】 代码的坏味道总结 Bad Smell (一) (重复代码 | 过长函数 | 过大的类 | 过长参数列 | 发散式变化 | 霰弹式修改)

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  2. 重构系列之重构的标志:《重构》代码的坏味道

    重复代码 1. 表现:同一个类的两个函数含有相同的表达式. 方案:提炼函数. 2. 表现:两个互为兄弟的子类内含有相同表达式. 方案:函数上移,推入超类. 3. 表现:如果两个毫不相关的类出现重复代码 ...

  3. java检验两个文章重复率,代码重构:代码的坏味道

    今天在向maven仓库发文件,干不了什么活,于是就在osc中转转,转到共享代码里,看到一篇 Java 解析/读取XML 文件  @老枪 于是就用这个例子来典型分析一下. 原文如下: 1.[代码]stu ...

  4. 读书笔记之《重构》第三章—代码的坏味道

    第三章 代码的坏味道 这一章告诉我们,什么样的代码需要去重构,该用什么方法.寻找代码的坏味道,就是从代码中找出特定的结构,这些结构指出重构的可能性.寻找这些结构,需要学会判断,判断一个类里面有多少实例 ...

  5. 【重构之法】代码的坏味道

    代码的坏味道 坏味道意指代码中出现的可以被改进的地方.当你嗅到坏味道的时候,也就意味着重构的时机到了. 重构就是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修 ...

  6. 重构-改善既有的代码设计-------代码的坏味道

    重构-改善既有的代码设计 代码的坏味道 神秘命名(Mysterious Name) 给函数.变量.模块和类命名时,要使它能清晰地表明自己的功能和用法,使得写下的代码直观明了. 常用重构手法为重命名,包 ...

  7. 代码的坏味道与重构技术

    一.前言 本文大部分内容.图片来自Martin Flower的<Refactoring>一书以及refactoringguru网站(一个很棒的网站),之前在博客发表过,这次属于整理后重新发 ...

  8. 《重构 改善既有代码的设计》之代码的坏味道

    1 简介 知道"如何"不代表知道"何时".决定何时重构.何时停止和知道重构机制如何运转一样重要. 从我们的经验来看,没有任何量度规矩比得上一个见识广博者的直觉. ...

  9. Refactoring之——代码的坏味道(一)过长方法

    1 代码的坏味道 重构一书中提到了22种代码的坏味道,大致可以分为几类. 识别代码的坏味道,有助于发现代码的潜在问题,从而可以有的放矢的修改现有代码,使之不断完善. 1.1 Bloaters(臭鲱,暂 ...

最新文章

  1. SQL Server查询某个字段存在哪些表中
  2. 开启Apache mod_rewrite模块完全解答
  3. css平台HTDC币,是否应该从最新的设置中应用CSS规则?
  4. Linux中append函数的用法,linux C代码 open函数参数:O_APPEND问题求助
  5. python程序分析,用Python编写分析Python程序性能的工具的教程
  6. 逻辑回归(LR)个人学习总结篇
  7. 春晚红包:挺住的百度和崩坏的应用商店
  8. numpy 归一化_图卷积网络到底怎么做,这是一份极简的Numpy实现
  9. asm扩容流程_AIX之ASM存储扩容
  10. 《pro Spring》学习笔记之Spring HTTP 远程方法调用
  11. Long型转换成IP段String、StringIP段转换成Long型
  12. linux 快速合并文本文件,Linux-Linux中高效合并文本文件的方法
  13. 基于Springboot+MySQL的个人健康监控管理系统
  14. 进制转化(北理乐学编程题目)
  15. Aspose.PSD for Java 21.6 Crack
  16. 使用Aria2下载百度网盘和115的资源
  17. C语言编程>第二十六周 ⑥ 请补充fun函数,该函数的功能是:按 “0”到 “9”统计一个字符串中的奇数数字字符各自出现的次数,结果保存在数组num中。注意:不能使用字符串库函数。
  18. Nginx更新https证书,三步走
  19. 单片机控制雷达测距模块HC-SR04测量距离(通过测试)
  20. python处理手写签名为电子签名

热门文章

  1. 9月开学季CSDN高校俱乐部专家巡讲讲师招募
  2. 使用Sigar包获取操作系统信息
  3. bios设置raid启动模式Linux,手把手教你做raid,各主板raid开启设置方法
  4. 记录一个设备旁挂ikuai后收不到回包TTL为1的问题
  5. OIM Training Lab 1
  6. Remix连接本地项目(Solidity)
  7. python抓取视频违法吗,科学网—【python爬虫】抓取B站视频相关信息(一) - 管金昱的博文...
  8. 剑指offer73:狒狒吃香蕉
  9. matlab自定义函数拟合散点
  10. 从“我爸是李刚”到高校教师聘用体制的改革