第 1 章 重构,第一个示例
这是我个人的编码风格:永远将函数的返回值命名为“result”
如果重构引入了性能损耗,先完成重构,再做性能优化。
好代码的检验标准就是人们是否能轻而易举地修改它。
小的步子可以更快前进,请保持代码永远处于可工作状态,小步修改累积起来也能大大改善系统的设计。
第 2 章 重构的原则
重构(名词):对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
重构是为了让代码“更容易理解,更易于修改
重构的意义不在于把代码库打磨得闪闪发光,而是纯粹经济角度出发的考量。我们之所以重构,因为它能让我们更快——添加功能更快,修复 bug 更快
Don Roberts 给了我一条准则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。
每次要修改时,首先令修改很容易(警告:这件事有时会很难),然后再进行这次容易的修改。
如果重写比重构还容易,就别重构了。这是个困难的决定。如果不花一点儿时间尝试,往往很难真实了解重构一块代码的难度。决定到底应该重构还是重写,需要良好的判断力与丰富的经验
第 3 章 代码的坏味道
神秘命名(Mysterious Name)
改名不仅仅是修改名字而已。如果你想不出一个好名字,说明背后很可能潜藏着更深的设计问题。为一个恼人的名字所付出的纠结,常常能推动我们对代码进行精简。重复代码(Duplicated Code)
过长函数(Long Function)
每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途(而非实现手法)命名过长参数列表(Long Parameter List)
把函数所需的所有东西都以参数的形式传递进去全局数据(Global Data)
把全局数据用一个函数包装起来,至少你就能看见修改它的地方,并开始控制对它的访问。随后,最好将这个函数(及其封装的数据)搬移到一个类或模块中,只允许模块内的代码使用它,从而尽量控制其作用域。可变数据(Mutable Data)
可以用封装变量来确保所有数据更新操作都通过很少几个函数来进行,使其更容易监控和演进
。。。。。。
我们希望软件能够更容易被修改——毕竟软件本来就该是“软”的。一旦需要修改,我们希望能够跳到系统的某一点,只在该处做修改。
你看到一段代码有着长长的注释,然后发现,这些注释之所以存在乃是因为代码很糟糕。这种情况的发生次数之多,实在令人吃惊。我们首先应该以各种重构手法把坏味道去除。完成之后我们常常会发现:注释已经变得多余了,因为代码已经清楚地说明了一切