写在最开始为什么会想着读这本书?两个原因。第一,工作中对我自己写的代码不太放心,修改应该是早晚的事,那么先了解一些方法;第二,我更愿意读这类和编程语言没有太多关联的书(还有例如算法、设计模式等等),这样的话了解了思想就算以后不用java也能有所帮助,这样读起来感觉更划算。 前前后后看这本书花了一个半月,毕竟拖延症晚期。正好在这一个半月中,工作上需要扩展一些功能,感觉就能够用上书中的一些知识,很开心,因为之前总说多看点书总是好的,你不知道哪天就能用上以前看到的知识,现在呢,这一步来得更快了。不过呢,感觉是用上了,但是有没有真的理解,以及真的是不是这么用的,就得再观察一下了。
简单的概括整本书的一个结构: 第一二章介绍了什么是重构; 三四章大概说了重构前的一些准备(也可以理解为何时重构); 第五章是整本书的一个格式上的约定(我是这么理解的,至少我觉得实际工作中记录重构不需要这样来做); 从第六章开始到第十一章都是作者列出的一些具体重构方法,在我的这篇文字中我也尽量列出,更多的时候可以当作是“知识点”列出来,实际需要的时候再回来查阅细看; 十二章的大型重构,也是总结了运用之前的各个重构方法完成大型项目的一些例子; 十三章我觉得是一个引申出来的章节,现实中怎么去推广使用这种方法(这书已经有些年头了,不知道这章的内容在现在是否还有实际意义); 十四章介绍了重构的工具,至今我也没有使用过,不多说; 十五章总结;最后还列出了本书的要点,这点让我感觉很好。
第1章 重构,第一个案例难以修改,可能会有两个原因,一是历史遗留下来的问题,系统已经多年岁月的冲刷,当年设计的架构已经很难支持现在的需求变更,二是当时确实没有考虑到;在稳定运行的系统中加入非必要的功能我是会有抵触的,加入新功能就面临着引入新bug的风险,但是呢很多时候并不是抵触就能不做。
看到这一段的时候笑了,看样子大部分的客户都一样,大部分的程序员也都遇到过同样的问题。
以下是第一章例子中,作者提到的一些建议:
第2章 重构原则什么是重构:
为什么重构:
什么时候重构:
第3章 代码的坏味道这一章的内容是比较有用的,列举了很多容易造成问题的“迹象”,可以借鉴本章节的内容,对照着看自己写出的代码是否有当中列举的,是不是能在写的时候就规避这些“坏味道”。
可以说重复代码是最常见的一种情况了。就像最近的一个项目,客户和我们对整个项目都是一边摸索一边前行,就会出现一些需求和原来的差不多,仅仅是参数、或者查询的条件稍微有些不同,但是在最开始的时候并不知道会有类似的需求,而且也不知道后续会不会还有修改,不断的重复的代码就越来越多。
这个在工作中也见到一些,一个函数参数过多的后果可能会难以理解,还有就是如果需要添加新的参数会变得更加困难。书中介绍了一种方法解决这个问题,用传入一个对象来替代参数列(后文中应该还会提到),将需要的参数全部放到这个对象中,这是一个很好的解决方法。我在实际开发中用Map代替了对象,感觉更方便一些,但是因为类型不确定的关系总感觉会很危险,这还要花时间来观察和验证。
这是不太理解的一点,因为时间工作中我也用了很多的switch语句。书中提到使用面向对象的多态来替换switch,每一个case就用一个新的子类来替代。我还是觉得还是需要根据实际情况来看这个问题,也许我一个case分支中就三五句代码,为此新建一个类似乎也不太值得。这个问题继续关注吧。
关于注释这点也是很有意思的。我们总是讨厌其他人不写注释和文档,但是自己也不喜欢写注释与文档。书中给出了一种观点,你经常看到一段代码有着长长的注释,然后发现,这些注释之所以存在乃是因为代码很糟糕。因此,可以从注释中找到上述提到的“坏味道”,然后去除“坏味道”,最后使注释变得多余。当然这一切并不是说不写注释!
第4章 构筑测试体系测试的重要性啦,无论何时,测试都是很重要的了,自测是必须的,至少把自己能想到的情形先自己测试一遍。而且我认为测试和经验是有些关系的,踩过的坑多了就知道哪些地方可能会有坑,然后就能稍微有针对的去进行测试。 还有我想提的一点是,越是简单的改动越要测试,往往出错的地方都是测试的时候觉得根本不会有问题的地方(毕竟觉得有问题的地方都会花精力去测试)。
第5章 重构列表约定了一个之后使用的介绍重构方法的格式: 名称:…… 简短概要:…… 动机:…… 做法:…… 范例:……
第6章 重新组织函数
有一段代码可以被组织在一起并独立出来,将这段代码放进一个独立函数中,并让函数名称解释该函数的用途。 这应该也是编程过程最常用的一个方法,不管是不是刻意的去重构。将重复代码和过长的函数进行提炼。
第7章 在对象之间搬移特性面向对象编程的一个比较麻烦的问题——一件事到底该由哪个类来完成,后续工作中可以运用下列的重构方法修改最开始的设计。
第8章 重新组织数据
简单的说,就是给你的字段设置get和set方法,并且使用get、set方法去访问和修改字段。
其实我们的程序都是这样使用的,把用”|”分割的字符串分解成数组,然后根据不同位置的元素放到对象对应的属性当中。
这个地方学习了,我们就常常会有代表各个状态的常量数字,代码中看到一个个数字用于判断状态是很容易懵的,建立一个常量,起个看得懂的名字,对理解程序还是会有很大帮助的。 Static final int CONSTANT_XXXTYPE = 1 ;
将字段声明为private,提供相应的访问函数。
第9章 简化条件表达式
就是将if/then/else三个段落中分别提炼出独立函数。这样代码将会更清晰。
有关于断言,几乎没有在程序中使用过,有一种说法是,断言只应该出现在测试当中,因为不满足断言条件的在正常情况中都不允许出现。
第10章 简化函数调用
关于函数名称,我们的程序中有一个是最让我崩溃的,两个函数,函数名称相同、(最开始的时候)返回值也相同,只有参数列表不同,乍一看觉得两个函数就是一样的,更崩溃的是,其中一个函数当中还引用了另一个!简直红红火火恍恍惚惚…代码大概意思是下面这样,我一定要去改了它! Map sameName(String a , String b,int c){ doSomething(); …… Mapmap = sameName(a , c); doSomething(); …… return otherMap; } Map sameName(String a ,int b){ doSomething(); …… return map; }
这就是最开始在过长的参数列中提到的。运用一个对象包装所有需要的参数数据进行传递。该项重构的价值便在于缩短参数列。
看到这一节的时候,我决定接下去我要看的书是《设计模式》.
返回值的类型需要强制转换的时候,在函数return的时候进行类型强制转换,从而确定返回值的类型,而不是在接收到返回值之后再进行转换。
书中的意思是,我们常常会用返回“-1”类似的代码表示运行出错,此类情况用异常直接代替。
第11章 处理概括关系这一章主要用来处理继承相关的问题。主要也就是为了确定字段、方法到底应该放在子类还是超类当中,以及多个行为相似的类是否能提炼出超类等等。
第12章 大型重构第13章 重构,复用与现实实际情况中我们很少会有时间来重新审视自己原先的代码,我们总是在不断往既有代码中不停地加入新代码,以完成客户提出的新需求。 拒绝重构的原因有很多,我认为更关键的一点就是,我们的程序现在能够稳定运行,如果此时重构则可能会对程序造成破坏,这是有风险的。
第14章 重构工具本书出版的时候感觉支持重构的工具应该很少而且是不完善的,但是这么些年过去了,应该也有了很多的发展,有时间可以找一些来试试。 |
|