JBuilder2005实现重构之杂项重构
1、优化import
简而言之,通过优化import的设置可以达到以下的目的:
去除无用的import语句:如在类中没有使用任何包中的类,则这个包的import语句可以删除。
设置包的阈值:当前类引用包中类的数目大于这个阈值时,引入整个包(如import java.io.*),否则为包中每个被引用的类单独指定的一个import语句(如import java.io.File)。
设置包的排列顺序:按照一般的习惯,按包的常用程度从高到低进行排列,常用的包放在前面引入。一般情况下,JDK经典的包放在最前面(以java.为前缀),JDK扩展包紧跟其后(以javax.为前缀),接着是第三方类库包(如org.apache.*),再次是自己开发的公用类库,最后才是工程中的其他类。
通过Project->Project Properties...->Java Formating->在Imports设置页中切换到Threshold标
图 25 设置包阈值对话框
签页中通过Package import threshold指定包的阈值,默认为0表示进行优化import后,用通配符以整个包的形式分别引入。
你也可以勾选Always import classes项,将每个类用单独的import语句引入,这相当于将Package import threshold设置为无穷大。
在Imports设置页中切换到Sort Order标签页,在此指定import代码段的包引入顺序及格式。假设myrefactor.jpx工程中有一个myrefactor.sub1的子包,我们通过以下步骤将其置为import引入代码段的最后,并在前面添加一个空行:
1) 点击Add blank line在列表中添加一个<blank line>,表示在import代码段中添加一个空行。
2) 点击Add prefix...在弹出的Add Prefix对话框中选择myrefactor.sub1包。
3) 点击OK保存设置。
图 26 import代码段样式设置对话框
此外,还可以通过Move Up和Move Down调整包在引入代码段中的位置。列表中有一个<*>项,表示其他所有未匹配的包,如有一个以com.打开的包就放置在<*>的位置。
设置完后,在工程窗格的<Project Source>节点上右击,选择Format Package...在弹出的Fomcat Code对话框中确认选择Optimize imports项,按OK后,JBuilder对工程中所有的类进行import代码段进行优化重构。
2、自动添加异常捕捉
自动添加异常捕捉功能,从严格意义上说并不属性代码重构的范畴,因为编译期的异常是一定要有捕捉代码的,否则程序无法通过编译。但在某些情况下,自动添加异常捕捉就是地地道道的代码重构了,请看下面的代码:
代码清单 “面向编译”的异常捕捉1. public void autoCatch()
2. {
3. try {
4. FileInputStream fis = null ;
5. byte[] bArr = new byte[1024] ;
6. //会抛出FileNotFoundException
7. fis = new FileInputStream("D:1.txt") ;
8. //会抛出IOException
9. fis.read(bArr) ;
10. }
11. catch(Exception ex) {
12. }
13. }
第7行语句会抛出FileNotFoundExcetion,而第9行会抛出IOException,理应分别捕捉这两个异常,但是开发人员也许对异常并不感兴趣,所以直接捕捉Exception敷衍了事。由于Exception是所有异常的祖先类,所以这种异常捕捉方式并不会引发编译错误,但它确实没有做什么有意义的事,只是为了通过编译罢了,称之为“面向编译”的异常捕捉,即只为通过编译。
程序发生异常时,要么用throws将异常踢给调用者,要么直接处理异常。如果打算直接处理异常,就必须对代码中的异常分别处理,这样才可以能够异常的详细信息,以及具体是哪个异常引起的。对于程序的用户来说,详细的错误信息可以让他们更直接知道问题所在,而程序的调用者来说,具体的异常可以让他们进行分别对待,分别处理,这种处理异常的方式称为“面向问题”的异常捕捉。我们拟将这段代码重构为以下的形式,如下所示:
代码清单 16 “面向问题”的异常捕捉1. public void autoCatch()
2. {
3. FileInputStream fis = null ;
4. byte[] bArr = new byte[1024] ;
5. try {
6. //会抛出FileNotFoundException
7. fis = new FileInputStream("D:\1.txt") ;
8. //会抛出IOException
9. fis.read(bArr) ;
10. }
11. catch(FileNotFoundException ex) {
12. System.out.println("D:\1.txt文件不存在,请检查") ;
13. }
14. catch(IOException ex) {
15. System.out.println("D:\1.txt文件读写发生异常,异常信息为:" +
16. ex.getMessage()) ;
17. }
18. finally {
19. if(fis != null) {
20. try {
21. fis.close() ;
22. }
23. catch(IOException ex1) {
24. System.out.println("关闭文件输入流的时候发生异常,异常信息为:
25. " + ex1.getMessage()) ;
26. }
27. }
28. }
29. }
你需要做的是删除掉原来的“面向编译”的异常捕捉代码(即第5行和第10~12行),选中第6~9行,按Ctrl+Shift+C,JBuilder自动分析这段代码,发现这段代码易做图有引发两个异常,分别为每个异常生成两个捕捉块,代码如下:
代码清单 17 通过Ctrl+Shift+C自动添加异常捕捉代码块1. public void autoCatch()
2. {
3. FileInputStream fis = null ;
4. byte[] bArr = new byte[1024] ;
5. try {
6. //会抛出FileNotFoundException
7. fis = new FileInputStream("D:\1.txt") ;
8. //会抛出IOException
9. fis.read(bArr) ;
10. }
11. catch(FileNotFoundException ex) {
12. }
13. catch(IOException ex) {
14. }
15. }
然后,我们再手工添加上finally代码处理块,因为资源打开后,一般需要显示关闭,以便快速释放资源。调整的最后代码如代码清单 16所示。
实战经验:
虽然可以通过Ctrl+J以模板的方式快速录入try...catch代码块,但是笔者还是倾向于用Ctrl+Shift+C自动生成异常捕捉块,这样不但提高了代码编写的速度,还保证异常捕捉代码块的规范性:为所有可能的异常分别生成一个捕捉块,且将特殊的异常放在前面,一般性的异常则放在后面。3、部署描述文件
如果你的工程中有一个Web模块,依据你所选用的Web技术可能会有多个不同的部署描述文件,你可以直接通过这些部署描述文件进行重构类名重构,如下面是一段Struts关于FormBean的部署描述信息:
代码清单 18 Struts有关formBean的部署描述文件1. <struts-config>
2. <form-beans>
3. <form-bean name="untitled1ActionForm" type="myrefactor.Untitled1ActionForm" />
4. </form-beans>
5. </struts-config>
在编译器中打开需要重构的部署描述文件,将光标移到<form-bean>标签的type属性值中,点击右键->Refactoring->Rename Class for “UntitleActionForm”,如下图所示:
图 28 在部署描述文件中重构类名的对话框
在New name中键入UserActionForm,点击OK,JBuilder不但更改部署描述文件中的type属性值,还将该属性所对应的类名进行更名重构。
4、EJB
因为EJB设计器中知道一个EJB所有引用的类和接口,所以必须通过EJB设计器对EJB类进行更名。如果在编辑器或UML浏览器中对EJB文件进行重命名重构,你将看到以下的警告信息:WARNING: You are refactoring an EJB file. This may require
that you change some source code and the deployment
descriptor by hand. We recommend using the EJB designer for
most refactoring scenarios.
如果你选择继续,则需要手工更改其他相关的文件,并同时更改部署描述文件中的相关内容,稍有不慎即会发生遗漏,所以应当尽量在EJB设计器中来重构。
5、代理
假设一个A类有一个成员类(B类),B类有一个方法foo(),如果C类想通过A类调用B类的foo()方法,则必须这样:A aObj = new A();
aObj.bObj.foo();
实际情况可能会有更多的衔接层,为了减少这种层层嵌套间接调用所造成臃肿的代码,有时我们直接通过代理使代码显得简洁。在A类中提供一个代理方法foo(){bObj.foo();},这样C类只要这样就可以访问B类的foo()方法了:A aObj = new A();
aObj.foo();
JBuilder提供了一个代理成员类方法的方便功能,来看下面的MultiAnimal类:
<
补充:软件开发 , Java ,