2,8阅读
第一章 第一个案例
在此案例中使用了,
方法的提取(extract method),方法的移动(move method),临时变量的清除,变量及函数名重构,switch类型重构(replace type code with state/strategy)等。
重构使得代码功能更加好的被复用,偏于维护和修改。
注意:
switch语句的属性尽量不要是另一个对象的数据,最好在自己的数据基础上进行
第二章 重构原则
何为重构:(名词)不改变软件可观察行为的前提下,提供可理解性,降低其修改成本。
何为重构:(动词)使用一系列重构方法,在不改变软件可观察行为的前提下,改变其结构。
重构能帮我们找到bug,提高编程速度。
何时重构:
重构不是为了重构而重构,重构应该随时随地进行,是因为当你想做别的事情时,重构能帮你把事情做的更好。
《三次法则》第一次尽管去做,第二次做类似的事情会厌烦还能勉强去做,第三次做类似事情就要重构。(事不过三,三则重构)。
当我们添加新功能时需要重构,可以帮我们更深刻的理解之前的代码。
当我们修补错误的时候需要重构,可以帮助我们更好的理解代码并找到问题或bug。
当我们复审代码时需要重构,可以帮助改善团队开发状况,有助于知识的传播,使代码可以更加清晰的阅读,更容易理解。
何时不该重构:代码太过混乱,满是错误,这是我们可以选择重写。
重构与设计:前期良好的设计可以帮我们节省返工的高昂成本。
性能优化:代码后期维护比较合适,针对后期运行期间特点的程序进行优化,因为大部分代码不是经常被执行的,优化的意义不大。
第三章 代码的坏味道
代码使用的时机:1.重复代码使用提取方法。2.两个或多个子类使用相同的方法,将其推入超类中。3.相似的代码可以使用模板方法。
4.两个毫不相关的类中的重复代码,将其提炼出放到一个独立的类中。
过长函数:拥有短对象的函数过的会比较好。
过大的类:如果利用一个类做太多事情,往往会出现太多实例变量,一旦如此,重复代码就会接踵而来。
过长参数列:可以使用对象代替过长的参数。
divergent change发散式变化:某个类因为不同的原因在不同的方向上发生变化, 此处理解为高内聚低耦合的原理。
shotgun surgery(散弹式修改):与divergent change相反,每遇到某种变化时,需要在许多不同的类内部做许多小修改,这时需要将变化的方法
移动到同一类中。
feature envy(依恋情结):函数对某个类的兴趣高于自身所处类的时候,通过时某个函数为了计算某个数据值而调用另一个对象半打的函数,这时
我们需要将此方法移动到依恋的类中。有时候函数只有一部分依赖的地方,则需要先将此部分提取出来再进行移动。
data clumps(数据泥团):多个类的字段或函数中参数如果有过多重复的数据,这时可以考虑将其提炼到一个新的类中。
基本类型偏执:可以将基本类型替换成对象形式。
switch惊秫现身:尽量少用switch语句,可以将其转化成多态。
平行继承体系:比如多个超类前缀命名很相似时,考虑是否出现了高内聚问题。这时可以将方法移动合并重复的超类。
lazy class 冗余类:如果某个类几乎不适用,或者最初设计来应对某种变化,而变化不会再发生,这种时候可以考虑inline class.
speculative generality 夸夸其谈未来性:多余的抽象类,参数,函数等实用inline class.
temporary field 令人迷糊的临时变量:可以将特定情况才会用的临时变量抽取到一个新的class中,并将相关方法移动过去。
messages chains 过度耦合的消息链:如果你发现某种情况一个对象调用另个对象,另个对象又调用另个对象,出现一长串的调用链,
这时如果修改任何一个类的变化都会导致客户端做出相应的修改。
过多的注释:不要滥用注释。
第四章 构筑测试体系
测试能够帮助我们找到系统的bug,并且能够使我们更深刻的理解项目的设计思想。好的测试体系是帮助我们重构的基础,步步为营。
第五章 重构列表
主要讲述作者对重构的各种手法的实践。讲述的标准为 “名称;概要;动机;重构后结果怎样解决了什么问题”
第六章 重新组织函数
6.1 extract method 提炼函数
动机:函数的细粒度越大,被复用的机会越高,函数的命名越清晰,越容易被人理解。
6.9 替换算法
String foundPerson(String[] people){
for(int i=0;i<people.length;i++){
if(people[i].equals("Don")) return "Don";
if(people[i].equals("John")) return "John";
if(people[i].equals("Kent")) return "Kent";
}
return "";
}
String foundPerson(String[] people){
List candidates = Arrays.asList(new String[]{"Don","John","Kent"});
for(int i=0;i<people.length;i++){
if(candidates.contains(people[i]))
{
return people[i];
}
}
return "";
}