eclipse的重構功能詳解

使用Eclipse進行代碼重構 

重構是軟件開發過程當中保證代碼質量很是重要的手段,而手動進行重構代碼的話,很容易引入一些低級錯誤(例如,單詞拼寫錯誤),從而致使浪費大量沒必要要的時間。Eclipse爲重構提供了很強大的支持,很大程度上用戶沒必要爲重構的筆誤而再煩惱。 
在Eclipse中,可使用JDT提供的重構功能對Java項目、類和其成員進行重構,全部這些被重構的部分均可以當作一個JDT能識別的Java元素。要執行重構,首先必須選擇相應重構的Java元素,一些重構是適合任何Java元素的,而一部分重構只適合特定的Java元素,幾乎全部的重構都可以在重構對話框中看到預覽的效果。 

要使用Eclipse的重構功能,能夠先選擇相應的Java元素(Java工程中的資源,包括工程、文件、方法、變量等),經過右鍵菜單選擇Refactor菜單下的重構功能,如圖1所示。 

 


圖1 選擇重構菜單 


在Eclipse中,能夠簡單的把重構分爲結構性重構、類級別重構和類內部重構,每種類型的重構又分別包含了一些具體的實現,接下來將分別介紹Eclipse如何對Java元素進行重構。 

提示:在JDT可識別的範圍內,能夠認爲工程中資源都是Java元素,包括Java文件名、類、方法、變量等。 

結構性重構 

結構性重構涉及到JAVA元素的物理結構的改變,包括「Rename」、「Move」、「Change Method Signature」、「Convert Anonymous Class to Nested」和「Move Member Type to New File」,下面將一一介紹這些重構在Eclipse中的實現。

1. Rename 

Rename重構的功能就是重命名Java元素。雖然能夠經過手動修改文件的文件名或其它Java元素的名稱,但這種方式不會更新與此Java元素相關聯的引用,用戶必須手動查找和此Java元素相關的位置,而後進行手動修改。經過手動修更名稱的方式,形成筆誤的可能性會太太增長。經過Eclipse提供的Rename的功能,Eclipse會自動完成更新相關引用的操做。 
當Java元素的命名不清晰或功能發生改變的時,爲了保持代碼的可讀性,能夠經過Eclipse的重構功能重命名Java元素。選擇相應的Java元素,選擇右鍵Refactor菜單下的Rename菜單,能夠對當前選擇的元素進行重命名,在彈出的重命名對話框中修改相應的元素名稱便可,例如修改一個包的重命名,如圖2所示。 


 

圖2 Rename對話框 


要修改包名的同時,能夠選擇是否更新引用和更新子目錄,甚至是非Java文件也能夠選擇性的更新。選擇Preview按鈕能夠預覽重命名重構後的效果,如圖3所示。 


 

圖3 預覽重命名包名 

能夠查看預覽的內容是否一致,確認是否要進行重命名的重構。能夠進行重命名的Java元素有Java項目、Java文件、包、方法和屬性字段等。 

提示:非Java項目和Java文件等也能夠經過重構菜單的Rename進行重命名。 

2. Move 

Move的重構和Rename的重構相似,它能夠把一個Java元素從一個地方移動到另外一個地方,Move的重構主要用來移動一個類到不一樣的包下。首先選中一個Java文件,選擇Refactor菜單下的Move菜單項,彈出Move的重構對話框,如圖4所示。 

 

圖4 Move對話框 


能夠選擇是否更新引用,設定移動文件重構的一些參數。 

提示:也能夠經過拖動的方式把一個文件從一個包移動到另外一個包,實現移動文件的重構。 

3. Change Method Signature 

「Change Method Signature」重構的功能是改變方法的定義,例如改變方法的參數名稱、類型和個數、返回值的類型,方法的可見性以及方法的名稱等。 

要改變方法的定義,能夠先選擇方法,經過右鍵菜單選擇Refactor菜單的「Change Method Signature」子菜單項,彈出「Change Method Signature」對話框,如圖5所示。 


 

圖5 「Change Method Signature」對話框 


能夠經過「Change Method Signature」對話框改變方法的參數名稱、類型和個數、返回值的類型,方法的可見性以及方法名稱等。 

4. Convert Anonymous Class to Nested 

「Convert Anonymous Class to Nested」重構的功能是把匿名類改爲內部類,這樣同一個類的其它部分也能夠共享此類了。 
例若有例程1所示的類。 

例程1 KeyListenerExample.java 

public class KeyListenerExample { Display display; Shell shell; KeyListenerExample() { display = new Display(); shell = new Shell(display); shell.setSize(250, 200); shell.setText("A KeyListener Example"); Text text = new Text(shell, SWT.BORDER); text.setBounds(50, 50, 100, 20); text.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { System.out.println("key Pressed -" + e.character); } public void keyReleased(KeyEvent e) { System.out.println("key Released -" + e.character); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } public static void main(String[] args) { new KeyListenerExample(); } } 

在KeyListenerExample類有一個匿名類,實現了KeyListener接口,能夠把這個匿名類改爲內部類,首先選擇匿名類,右鍵選擇Refactor的「Convert Anonymous Class to Nested」菜單,輸入內部類的名稱,如圖6所示。 


 

圖6 「Convert Anonymous Class to Nested」對話框 


重構後的結果是Eclipse爲此建立了一個內部類,名稱爲TestKeyListener,重構後的代碼如例程2所示。 
例程2 重構後的KeyListenerExample.java 

public class KeyListenerExample { private final class TestKeyListener implements KeyListener { public void keyPressed(KeyEvent e) { System.out.println("key Pressed -" + e.character); } public void keyReleased(KeyEvent e) { System.out.println("key Released -" + e.character); } } Display display; Shell shell; KeyListenerExample() { display = new Display(); shell = new Shell(display); shell.setSize(250, 200); shell.setText("A KeyListener Example"); Text text = new Text(shell, SWT.BORDER); text.setBounds(50, 50, 100, 20); text.addKeyListener(new TestKeyListener()); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } public static void main(String[] args) { new KeyListenerExample(); } } 

也能夠經過「Convert Anonymous Class to Nested」對話框定義新生成的內部類的可訪問性。 

5. Move Member Type to Top Level 

經過「Move Member Type to Top Level」的重構方式,能夠把內部類改爲非內部類,而且從新建立一個新的文件,這樣其它的類就能夠共享此類。 

例程2建立了一個內部類TestKeyListener,如今能夠經過「Move Member Type to Top Level」重構的方式,把TestKeyListener放入一個單獨的類中。首先選擇TestKeyListener類,從右鍵菜單Refactor中選擇「Move Member Type to Top Level」,打開「Move Member Type to Top Level」對話框,如圖7所示。 


 

圖7 「Move Member Type to Top Level」對話框 


經過上面「Move Member Type to Top Level」重構,能夠把內部類改爲非內部類。 

提示:有些時候,重構並非一步完成的,能夠一步一步重構,例如,首先把匿名類改爲內部類,再接着把內部類改爲非內部類。 


類級別重構 

類級別重構有以下一些: 

1. Push Down 

「Push Down」重構功能是把父類的方法和屬性移動到全部的子類中,父類的方法能夠選擇性的保留抽象方法。首先選擇父類,右鍵選擇Refactor菜單的「Push Down」菜單項,能夠經過「Push Down」對話框選擇重構,如圖8所示。 


 

圖8 「Push Down」對話框 


「Push Down」重構在從新設計類的時候是很是有用的,它能夠比較有較的改善類的繼承關係,清楚定義類的行爲。 

2. Pull Up 

「Pull Up」重構和「Push Down」重構正好相反,它的做用是把方法和屬性移動到其父類中去。選擇須要重構的子類,從右鍵菜單選擇Refactor菜單的「Pull up」菜單項,經過「Pull Up」對話框進行重構,如圖9所示。 


 

圖9 「Pull Up」對話框 


提示:「Pull Up」重構和「Push Down」重構後可能會出錯,在使用此重構的同時,應該先弄清楚某些方法中是否有引用到其它方法或屬性。 

3. Extract Interface 

「Extract Interface」重構可以從一個已存在的類中提取接口,它能夠從某個類中選擇方法,把這些方法提取到一個單獨的接口中。選擇提取接口的類,右鍵選擇Refactor菜單的「Extract Interface」菜單項,打開「Extract Interface」對話框,如圖10所示。 


 

圖10 「Extract Interface」對話框 


單元OK按鈕,將會提取TestInterface的接口,提取接口後,當前選擇的類將會實現此接口。 

提示:只有公用方法才能夠被提取爲接口的方法。 

4. Generalize Declared Type 

「Generalize Declared Type」重構可以改變變量、參數、屬性以及函數的返回值的類型,能夠把這些類型改爲其父類的類型。在Refactor菜單中選擇「Generalize Declared Type」,如圖11所示。 


 

圖11 「Generalize Declared Type」對話框 


單擊OK按鈕,可以把聲明的類型改爲當對話框中選擇的類型。 

5. User Supertype Where Possible 

「User Supertype Where Possible」重構可以用某一個類的父類的類型替換當前類的類型,選擇須要被替換引用的類。在Refactor菜單中選擇「User Supertype Where Possible」打開「User Supertype Where Possible」對話框,如圖12所示。 


 

圖12 「User Supertype Where Possible」對話框 


「Generalize Declared Type」重構和「User Supertype Where Possible」重構在面向接口編程方面是頗有用的,能夠把引用的對象儘量用接口進行實現。 

提示:「User Supertype Where Possible」重構將替換其它類中的引用,要想看到重構的效果,應該找到其它類引用的位置,此操做不會修改當前文件。 


類內部重構 

類內部重構有以下一些: 

1. Inline 

「Inline」重構能用函數的內容替換掉函數的引用。首先選擇函數的引用,在Refactor菜單中選擇「Inline」打開「Inline」對話框,如圖13所示。 

 

圖13 「Inline」對話框 


單擊肯定按鈕,Eclipse將會用方法實現的部分替換引用的部分,即當前不採用方法調用的方式進行操做。也能夠選擇「All invocations」和「Delete method declaration」,Eclipse會替換掉全部引用方法的位置,而且刪除方法。 

提示:Inline會用方法的實現部分替換全部調用方法的地方。 

2. Extract Method 

「Extract Method」重構和「Inline」重構相反,它可以從冗長的方法中提取小的方法,把大的方法分解成多個小方法來實現,經過此重構可以使代碼看上去更簡單漂亮,也很大程度上提升代碼的複用性。能夠選擇要提取方法的代碼,在Refactor菜單中選擇「Extract Method」打開「Extract Method」對話框,如圖14所示。 


 

圖14 「Extract Method」對話框 


「Extract Method」重構是很是好的重構方式,可以把大的方法體重構成多個方法的實現,使代碼更清楚易懂。 

提示:「Extract Method」重構和「Inline」重構是對應的,有些時候爲了組織一些不合的函數,能夠先經過「Inline」的方式生成一個大的函數,再經過「Extract Method」來重構大的函數,使代碼更趨於合理。 

3. Extract Local Variable 

在開發過程當中,使用變量代替表達式是很是好的,這樣能使代碼更容易被理解。Eclipse中能夠經過「Extract Local Variable」重構實現提取局部的表達式。首先選擇表達式,在Refactor菜單中選擇「Extract Local Variable」打開「Extract Local Variable」對話框,如圖15所示。 

 

圖15 「Extract Local Variable」對話框 


4. Extract Constant 

「Extract Constant」重構和「Extract Local Variable」重構相似,它能夠把表達式定義爲常量,另外「Extract Constant」重構可以設定常量的可見性。選擇表達式,在Refactor菜單中選擇「Extract Constant」打開「Extract Constant」對話框,如圖16所示。 

 

圖16 「Extract Constant」對話框 


5. Introduce Parameter 

「Introduce Parameter」重構能夠經過函數中的表達式、變量或引用爲函數添加新的參數,還可以自動更新引用此函數的其它位置的默認參數。要想進行「Introduce Parameter」重構,能夠選擇表達式、變量或引用。在Refactor菜單中選擇「Introduce Parameter」打開「Introduce Parameter」對話框,如圖17所示。 


 

圖17 「Introduce Parameter」對話框 


6. Introduce Factory 

「Introduce Factory」重構可以爲類建立工廠方法。首先選擇須要建立工廠方法的類的構造函數,在Refactor菜單中選擇「Introduce Factory」打開「Introduce Factory」對話框,如圖18所示。 


 

圖18 「Introduce Factory」對話框 


在「Introduce Factory」對話框中,能夠輸入工廠方法的名字,以及工廠類,Eclipse將會自動根據構造函數建立工廠方法。 
提示:工廠類應該已經存在,一般能夠在一個工廠類中爲多個關聯的類建立工廠方法,因此在使用「Introduce Factory」重構前,應該先建立好工廠類。 

7. Convert Local Variable to Field 

「Convert Local Variable to Field」重構可以把局部的變量轉換成類中的全局變量。首先選擇要轉換的局部變量,在Refactor菜單中選擇「Convert Local Variable to Field」打開「Convert Local Variable to Field」對話框,如圖19所示。


 

圖19 「Convert Local Variable to Field」對話框 


在「Convert Local Variable to Field」對話框中,還可以修改變量的名稱以及變量的可見性。 

8. Encapsulate Field 

「Encapsulate Field」重構可以包裝屬性的可訪問性,以及生成訪問的方法。首先選擇要包裝的屬性,在Refactor菜單中選擇「Encapsulate Field」打開「Encapsulate Field」對話框,如圖20所示。 


 

圖20 「Encapsulate Field」對話框 


一般經過「Encapsulate Field」能夠生成get和set方法。在「Encapsulate Field」對話框中能夠輸入屬性的訪問方法的名稱,以及方法生成的位置和方法的可見性。 

提示:經過右鍵菜單的Source菜單也能生成相應的get和set方法。 

Undo and Redo 

Eclipse的自動重構功能可以很好的支持各類程序元素的重命名,並自動更新相關的引用。Eclipse可以支持方法、字段在類之間移動,並自動更新引用,較好地支持內聯字段、函數的更新替換,較好地支持抽取方法、變量等程序元素。 

重構的過程是一個不斷嘗試和探索的過程。Eclipse的重構支持撤銷和重作,而且可以預覽重構結果,這些是很實用的功能。要想執行撤消和重作(Undo and Redo)的功能,能夠直接按快捷鍵Ctrl+Z以及Ctrl+Y,也能夠選擇Edit菜單的Undo和Redo操做。 

提示:雖然Eclipse對重構提供了很強大的支持,可是重構後代碼的測試是必不可少的,並且不能期望Eclipse可以解決全部重構的問題,有些時候手動重構仍是必須的。自動重構的理念應該是「工具輔助下的重構工做」,但開發人員仍然承擔很大一部分重構工做。 java

相關文章
相關標籤/搜索