重构2-重新组织函数
重构的基本技巧--小步前进,频繁测试。
模式是你希望到达的目标,重构则是到达之路。
在单进程软件中,你永远不必操心多么频繁地调用某个函数,因为函数的调用成本很低。但在分布式软件中,函数的往返必须被减至最低限度。
(Extract Method)提炼函数
含义:将一个复杂的大函数,提取整合为多个简单的小函数,通过函数名很明显的显示出此小函数要表达或者要展示的作用。
特别注意事项:
- 小函数的命名,要让别人立马可以看到函数要表达的含义。
- 对于大函数中的局部变量要特别小心,看是如何被调用和使用的。
- 对于需要返回参数的函数,尽可能使用多个小函数来处理返回值,尽量不要使用一个函数返回多个参数。
(Inline Method)内联函数
含义:函数的内部要表达的代码和函数名称一样简单时,就不需要单独使用函数,而直接使用本体就可。
int _nNumberOfLateDeliveries=10; private int GetRating() { return (moreThanFiveLateDeliveries()) ? 2 : 1; } private bool moreThanFiveLateDeliveries() { return _nNumberOfLateDeliveries > 5; }
对于上面的代码,在函数moreThanFiveLateDeliveries()中的函数主体特别简单,很容易看懂,那么此时就不需要使用此函数,直接在调用者GetRating()中,直接使用函数主体,以减少内联函数的使用。
特别注意事项
- 并不是所有的内联函数都没有价值,你需要找到有意义的内联函数,将无意义无用的内联函数优化掉。
(Replace Temp with Query)以查询取代临时变量
含义:如果函数中有临时变量保存着某一表达式的运算结果,则需要将此表达式提炼到一个独立函数中,将这个临时变量所有的引用点都替换为这个独立函数。
特别注意事项:
- 临时变量只是暂时的,而且只能在函数内部使用,如果将其所代表的表达式优化为一个单独的函数则可以多方进行调用。
- 确保提炼出来的函数无任何副作用。(该函数并不修改任何对象内容)
(Replace Method with Method Object)以函数对象取代函数
含义:对于大型函数,往往代码比较臃肿,那么就需要将大函数进行拆分,放再对象中成为对象中的字段,然后就可以在同一个对象中将这个大型函数分解为多个小型函数。
(Substitute Algorithm)替换算法
含义:如果想 将某一个算法替换为另一个更清晰的算法,将函数本体替换为另一个算法即可。
(Remove Assignments To Parameters)移除对参数的赋值
含义:代码对一个参数进行赋值,以一个临时变量取代该参数的位置。其实就是对于参数而已,如果可以在函数主体中之间使用,则就不需要在先将其赋值给参数,后使用参数。而且对于参数,最好只赋值一次,让其表示的函数单一。
(Split Temporary Variable)分解临时变量
含义:临时变量只能代表单一的表达式,如果它既不是循环变量,又不被用于收集计算结果。那么针对每次赋值,创造一个独立,对应的临时变量。
每个变量只承担一个责任,同一个临时变量承担俩件不同的事情,会另代码阅读者混乱糊涂。
(Introduce Explaining Variable)引入解释性变量
含义:对于函数中的复杂表达式,需要进行优化,将其重构成函数,赋值给一个临时变量,用临时变量来代替这个复杂表达式来向程序解释具体的用途。
对于临时变量,应该创建一个具体特殊含义,可以表达此复杂表达式的变量来用以说明。