前言
今天我们继续来讨论重新组织函数的重构手法.
正文
Introduce Explaining Variable(引入解释性变量)
示例
if((platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) && resize >0){
// do something
}
//我们可以看到上面的表达式特别长, 也特别难以理解, 所以我们可以引入解释性变量来改写
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize >0;
if(isMacOs && isIEBrowser && wasResized){
//do something
}
解释
通过上面的示例就能发现, 当我们的表达式特变长会变得很难理解, 这时候引入解释性变量就能提高我们对程序的理解. 所以这是很重要的重构手法.
但是大家有没有发现, 如果我们把每个表达式语句变为函数是不是更好呢? 也就是运用 Extract Method. 示例如下:
private boolean isIEBrowser(){
return browser.toUpperCase().indexOf("IE") > -1;
}
private boolean isMacOs(){
return platform.toUpperCase().indexOf("MAC") > -1;
}
private boolean wasResized(){
return resize >0;
}
if(isMacOs() && isIEBrowser() && wasResized()){
//do something
}
我们发现使用Extract Method, 使得表达式能被整个类使用, 更具有通用性. 所以我认为, 能使用Extract Method就尽量使用, 当不能使用Extract Method, 才使用Introduce Explaining Variable, 这种方式最好!(www.hedaoshe.com)
Split Temporary Variable(分解临时变量)
示例
double temp = 2*(_heigh+_width);
System.out.println(temp);
temp = _height*_width;
System.out.println(temp);
//我们发现上面的temp变量含糊不清, 不够语义化, 对temp进行了两次赋值很容易让我们摸不着头脑, 所以我们应该更加语义化
final double perimeter = 2*(_heigh+_width);
System.out.println(temp);
final double area = _height*_width;
System.out.println(temp);
解释
当我们使用临时变量时, 应该只有两种情况可以无意义, 那就是:循环变量
,结果收集变量
.
如果你发现临时变量用来保存一段代码的运算结果, 以便稍后使用. 那么这种临时变量应该只能被赋值一次, 并且起一个语义化的名字. 如果不这么做就会使阅读者糊涂, 理解起来更费劲.
总结
今天我们又介绍了两种函数重构手法, 一个是Introduce Explaining Variable
, 这个手法可以作为Extract Method
的补充, 因为Extract Method
更具有通用性. 另一个是Split Temporary Variable
, 对临时变量取名应该语义化, 方便阅读者理解.