分类: C/C++
2012-03-25 18:21:37
绝大多数情况下,一个过长的方法通常都是罪恶之源。
Extract Method 提取方法:如果一个方法里有大段代码,并且通常需要依赖注释来理解代码的内容,把这段代码提取出来,成为单独的方法。用方法名替代注释。
Inline Method 内联方法:有时一个方法做的事情实在是过于简 单,比如: bool greaterThanOne(int a) { return a > 1; },在调用这个方法时,不如直接直接使用这个方法的内容。这个方法的存在并没有什么意义,既没有增加程序可读性,也没有起到可重用的作用,反而增加函数调 用的开销。
Inline Temp 内联临时变量:函数里经常会用到临时变量来简化使用。比如int a = b + c,然后在需要 b+c 的值的时候使用a。内联临时变量意味着在所有使用到a的地方都直接使用b+c。这样做的目的通常是简化重构,比如Extract Method。
Replace Temp with Query 用查询方法代替临时变量: 在Inline Temp后,可以把一些很复杂的表达式用一个查询方法代替,比如上例中,可以有一个新的方法GetSum() { return b+c; }。这个重构通常是为了简化Extract Method,因为如果临时变量过多的话,很难把一个大函数分成多个小函数。
Introduce Explaining Varible 引入解释性变量: 用一个有意义的变量名来代替一个复杂的表达式。比如if (point.x > 0 && point.y > 0) {} 可以改写成 bool bIsPointVisible = point.x > 0 && point.y > 0; if (bIsPointVisible) {}。这样可以增强代码可读性。
Split Temporary Variable 分离临时变量:有时会 因为懒惰会给一个临时变量赋于各种不同的使命,比如 int temp = a+b; print(temp); temp = a-b; print(temp); 这时如果写成 int sum = a+b; print(sum); int sub = a-b; print(sub); 代码可读性增加了,同时还能消除temp被误用的可能性。
Remove Assignments to Parameters 去除参数赋值:函数传进来的参数,最好不要在函数体里改变它的值,除非它是个输出参数。比如 f(int a) {a+=5; int b=a*2;} 这样的话就会丢失a的值。不如这样:f(int a) { int temp = a+5; int b = temp*2; }
Replace Method with Method Object 用方法对象代替方法: 方法过长时,可以用Extract Method来提取代码。但是如果方法里的有很多临时变量,而这些变量又不能被Inline Temp或Replace Temp with Query简化时(比如临时变量被引用的地方过多),直接把这些临时变量放入一个对象,并调用这个对象的函数。比如 f() {....; int a = b+c; print(a); ...;} 可以加入一个函数对象 class fo { public fo(int a); void f(); } 这样f()的重构就可以写成 f() {...; int a = b+c; (new fo(a)).f(); ....}
Substitute Algorithm 替换算法:如果一个算法不清晰,找一个更清晰的算法。比如一个长长的if,else if 块,或许可以使用查询表的方法实现。