前几天北京图书大厦买了两本书<<重构,改善既有代码的设计>>与<<agile with="" web="" development="" rails=""></agile>><agile with="" web="" development="" rails=""></agile>
特意把书的代码一个字一个字粘出来,望能帮助我们这些开发人员对"重构"理解提供一些帮助,
当你有一段代码可以被组织在一起独立出来
将这段代码放进一个独立函数中,并让函数名称解释该函数的用途
函数的命名是非常重要的,以前我做开发的时候,从来我就不考虑这么多,只要这个函数能跑起来就行,我也不去管那么多,现在看了"重构",感觉它有另外一种思想,望大家好好学习!!
java 代码
- void printOwing(double amonut){
- printBanner();
- //print details
- System.out.println("name:"+_name);
- System.out.println(""amount:"+amount);
-
- }
重构后的代码:
java 代码
- void printOwing(double amonut){
- printBanner();
- printDetails(amount
- }
- void printDetails(double amount){
System.out.println("name:"+_name);
- System.out.println("amount:"+amount);
- }
可以看出现在变成了两个方法,把一部分语句抽出来做为一个方法!!
Extract Method 是最常见的重构方法之一。看见一个过长的函数或者一段需要注释才能让人理解用途的代码,就会将这个段代码放进一个独立函数中。
有数个原因造成简短面有良好的命名的函数。首先,如果每个函数的粒度都江堰市很小(finely grained),那么函数之间彼此复用的机会就更大了,其次,这会使高层函数代码读起来就像一系列注释;再者,如果函数都是细粒度,那么函数的覆写(override)也会更容易些.
作法:
- 创造一个新函数,根据这个函数的意图来给它命名
- 仔细检查提炼出的代码,看看其中是否引用了(作用域限于源函数)的变量(包括局部变量和源函数参数)
- 检查是否有(仅仅用于被提炼代码)的临时变量,如果有,在目标函数中将它们声明为临时变量
- 检查被提炼码,看看是否有任何局部变量的值被它改变,如果一个临时变量值被修改了,看看是否可以将被提炼码处理为一个查询(Query),并将结果值给相关变量,
- 将被提炼代码中需要读取的局部变量,当作函数传给目标函数
范例1):无局部变量(No Local Variables)
java 代码
- void printOwing()
- {
- Enumeration e =_orders.elements();
- double outstanding=0.0;
-
- //calculate outstanding
- System.out.println("*******************************");
- System.out.println("********* Customer Owes********");
- System.out.pritnln("*******************************");
-
- //calculate outstanding
- while(e.hasMoreElements()
- {
- Order each=(Order)e.nextElement();
- outstanding +=each.getAmount();
- }
-
- //print details
- System.out.println("name:"+_name);
- System.out.println("amount:"+outstanding);
- }
重构后:
java 代码
- void printOwing(){
- Enumeration e=_orders.elements();
- double outstanding=0.0;
- printBanner();
- //calculate outstanding
- while (e.hasMoreElements())
- {
- Order order=(Order)e.nextElement();
- outstanding +=each.getAmount();
}
-
- //print details
- System.out.println("name:"+_name);
- System.out.println("amount:"+outstanding);
- }
-
- void printBanner(){
- //print banner
- System.out.println("*******************************";
- System.out.println("*********** Customer Owes *****");
- System.out.println("*******************************"):
}
范例2):对局部变量再赋值(Reassigning)
java 代码
- void printOwing(){
- printBanner();
- double outstanding=getOutstanding();
- printDetails(outstanding);
- }
-
- double getOutstanding()
- {
- Enumeration e=_orders.elements();
- while (e.hasMoreElements())
- {
- Order each=(Order)e.nextElement();
- outstanding +=each.getAmount();
- }
- return outstanding;
}
Enumeration 变量 e 只有被提炼码中用到,所以可以将它整个搬到新函数中,double 变量oustanding 在被提炼码内外都被用到,所以我必须让提炼的新函数返回它。
java 代码
- double getOutstanding()
- {
- Enumeration e=_orders.elements();
- double result=0.0;
- while(e.hasMoreElements())
- {
- Order each=(Order)e.nextElement();
- result +=each.getAmount();
- }
- return result;
}
-
最后提炼成:
java 代码
- void print()
- {
- printBanner();
- double outstanding=getOutstanding();
- printDetails(outstanding);
- }
简单吧,呵呵