重构能帮助我们优化代码的结构,是软件更加容易被理解,bug更加容易被察觉,后期修改变得更加的方便。但是如果意识到哪些地方需要被重构,哪些地方应该选择哪些方法去重构就成了一个问题,为此我们首先要培养一种辨识能力,去发现代码中的臭味,这样才能为后期如何修改打下好的基础!
1.重复的代码
如果在一个以上的地方看到相同的程序结构,就应该设法将它们合二为一。
一个类里面多个函数中存在相同的部分:提炼出来变成一个新的函数,然后相同的地方调用这一个函数。
多个类总存在相同的部分:想看每个类中是否存在重复,存在的话,先提炼成一个函数;然后再将每个类的这个函数提炼出来放到一个新的类中,或者是将这个相同的部分提炼成为一个父类。
2.过长函数
一个函数越长越是难以理解;在早期的编程语言中,子程序的调用是会产生额外的开销的,因此使得人们不太乐意使用small method。但是现在的OOP语言几乎已经抹除的进程内的函数调用动作会产生额外开销的情况。而面向对象的编程思想还是会在阅读代码上形成阻碍在每个类的行为封装下。为此,一个良好的命名成为了我们理解代码深意的最有力的工具。
而如何分解一个函数,我们可以参考《重构》作者提出的观点:每当感觉需要以注释来说明点什么的时候,我们就需要将这个需要解释的东西写入到独立函数中。
3.过大类
当我们想要在一个单一的类中做很多的事情的时候,当中就会出现很多的临时变量,而一旦这样,那么重复的代码必然接踵而来。
为此我们可以进行如下步骤的蜕变:提取并建立新类->提取并建立子类->提取并建立接口
4.过长的参数列
过长的参数列往往会让我们难以理解,不易使用。为此我们应该这样做:
对于无法避免的参数,我们应该提取出来变成一个参数对象来传递;
另外如果我们如果我们发现某些参数如果在多个地方被用到,我们可以将这个参数提升为属性,并移除方法上面的形参,通过获取类上的属性进行操作。
5.发散式变化
因着外界带来的不同的影响,导致某一处的代码需要不同的变化。
将此代码对应的类建立一个兄弟类,然后根据外部不同的参数,让其调用不同的兄弟类进行相应的处理。
6.散弹式变化
因着外界带来的不同的影响,导致多处代码需要不同的变化
参看因着不同参数,到底有哪些地方的代码是需要被修改的,然后将这些被一个参数同时影响的代码提取出来放到一个地方
7.依恋情结
函数对某个类的兴趣远远超过当前类
将此函数放到涉及最多的类中
8.数据泥团
与过长的参数列一致
9.基本型别偏执
10.switch惊悚现身
11.平行继承体系
某个继承体系下面的子类和另一个继承体系下面的子类名称前缀完全相同
将这类相同的部分抽取出来,建立一个新的继承体系
12.累赘类(有待继续深入理解)
13.夸夸其谈未来性
不要将当前没有用到的功能或者属性放到类中
14.令人迷惑的暂时值域
一个类中某些实例变量只有在某种特殊的境况下才会被用到。
将这些实例变量提出来,放到新的类中
15.过度耦合的消息链(有待继续深入理解)
16.中间转手人(有待继续深入理解)
17.狎昵关系(有待继续深入理解)
18.异曲同工的类(有待继续深入理解)
19.不完善的程序库类(有待继续深入理解)
20.纯粹的数据类(有待继续深入理解)
21.被拒绝的遗赠
一个父类中存在的某些变量和方法定义在某些子类中并不会被用到
将这些不怎么会被用到的方法和变量提出来,变成这个父类的子类,对于要用到这些方法和变量的,只要继承这个子类就好了,如果不用到的,就继承父类
22.过多的注释
我们往往会将注释当成是去除代码坏味道的一种方法,从而对于当中存在可重构的代码熟视无睹
所以我们应该好好审视我们的代码,将我们需要的优化的代码先优化掉,然后再看看是否需要注释