选择显示字体大小

eclipse中自动重构实现探索

 本文用eclipse的自动重构功能对一个程序实例进行重构,目的是探索eclipse自动重构可以在多大程度上辅助重构这个过程。程序实例使用《refactoring:improving the design of existing code》一书中的例子。

   eclipse的自动重构功能能够很好地支持各种程序元素的重命名,并自动更新相关的引用。eclipse能够支持方法、字段在类之间移动,并自动更新引用。eclipse较好地支持内联字段、函数的更新替换。eclipse较好地支持抽取方法、变量等程序元素。

   重构的过程是一个不断尝试和探索的过程。eclipse的重构支持撤销和重做,并且能够预览重构结果,这些是很实用的功能。

   eclipse的重命名、抽取方法、移动、内联功能、更改方法特征符等代码结构级别的重构方法,是比较成熟同时也值得使用的功能。至于设计结构上的重构,eclipse还不能很好地支持。但是作者相信,自动重构的理念应该是"工具辅助下的重构工作",人仍然承担大部分重构工作。

   一、预备工作

   本文使用《refactoring:improving the design of existing code》一书第一章的例子。重构前的代码及每一步重构后的代码见附件。读者最好配合《refactoring:improving the design of existing code》一书阅读本文。

   eclipse使用如下版本:


   同时安装了中文语言包。

   二、重构第一步:分解并重组statement()

   目的:

   1、 把statement()函数中的swich语句提炼到独立的函数amountfor()中。

   2、 修改amountfor()参数命名

   重构方法:

   extract method
   rename method

   方法:

   1、选中swich语句的代码块,在右键菜单中选择"重构/抽取方法",出现参数对话框。eclipse自动分析代码块中的局部变量,找到了两个局部变量:each和thisamount。其中,each只是在代码块中被读取,但thisamount会在代码块中被修改。按照重构extract method总结出来的规则,应该把each当作抽取函数的参数、thisamount当作抽取函数的返回值。然而eclipse并不做区分,直接把这两个变量当作抽取新方法的参数,如图。


   我们的目的是把在抽取函数中不会被修改的each作为参数;会被修改的thisamount作为返回值。解决的办法是,把 double thisamount = 0; 这行代码移到switch语句的上面,变成这样:

double thisamount = 0;
switch(each.getmovie().getpricecode()){
  case movie.regular:
   thisamount += 2;
   if(each.getdaysrented()>2)
   thisamount += (each.getdaysrented()-2)*1.5;
   break;

  case movie.new_release:
   thisamount += each.getdaysrented()*3;
   break;

  case movie.childrens:
   thisamount += 1.5;
   if(each.getdaysrented()>3)
    thisamount += (each.getdaysrented()-3)*1.5;
   break;
}

   选中这段代码,在右键菜单中选择"重构/抽取方法",eclipse这次变得聪明点了,如图。


   选择"预览"按钮预先查看重构后的结果,符合我们最初的目的。


   选择"确定"按钮,重构后的代码片断如下:

public string statement() {
  double totalamount = 0;
  int frequentrenterpoints = 0;
  enumeration rentals = _rentals.elements();
  string result = "rental record for " + getname() + "\n";

  while(rentals.hasmoreelements()){
   rental each = (rental)rentals.nextelement();

  double thisamount = amountfor(each);

   frequentrenterpoints ++;
   if((each.getmovie().getpricecode())==movie.new_release &&each.getdaysrented()>1)
    frequentrenterpoints ++;

    result += "\t" + each.getmovie().gettitle() + "\t" +string.valueof(thisamount) + "\n";
    totalamount += thisamount;
  }

  result += "amount owed is " + string.valueof(totalamount) + "\n";
  result += "you earned " + string.valueof(frequentrenterpoints) + " frequent renter points";

  return result;
}

/**
* @param each
* @return
*/
private double amountfor(rental each) {
  double thisamount = 0;
  switch(each.getmovie().getpricecode()){
   case movie.regular:
    thisamount += 2;
    if(each.getdaysrented()>2)
     thisamount += (each.getdaysrented()-2)*1.5;
    break;

   case movie.new_release:
    thisamount += each.getdaysrented()*3;
    break;

   case movie.childrens:
    thisamount += 1.5;
    if(each.getdaysrented()>3)
     thisamount += (each.getdaysrented()-3)*1.5;
    break;
  }
  return thisamount;
}

   2、选中amountfor()的参数each,在右键菜单中选择"重构/重命名",在对话框中输入新的名称:arental,选择确定,amountfor()中所有each的引用全部被替换成新的名称。用同样的办法修改amountfor()中的局部变量thisamount为result。重构后的amountfor()代码如下:

/**
* @param arental
* @return
*/
private double amountfor(rental arental) {
  double result = 0;
  switch(arental.getmovie().getpricecode()){
   case movie.regular:
   result += 2;
    if(arental.getdaysrented()>2)
    result += (arental.getdaysrented()-2)*1.5;
    break;

   case movie.new_release:
   result += arental.getdaysrented()*3;
    break;

   case movie.childrens:
   result += 1.5;
    if(arental.getdaysrented()>3)
     result += (arental.getdaysrented()-3)*1.5;
    break;
  }
  return result;
}


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons