2011年11月15日

          java eclipse中的重構

          eclipse重構詳解

          博客分類:

          eclipserefactoring

          重構是對軟件內部結構的一種調整,目的是在不改變軟件行為的前提下,提高其可理解性,降低其修改成本。開發人員可以使用一系列重構準則,在不改變軟件行為的前提下,調整軟件的結構。

          有很多種原因,開發人員應該重構代碼,例如之前的開發人員代碼寫得很爛、自己以前設計時有缺陷、需求變更需要添加一些新的功能或修改原有功能等等。Martin Fowler在其著名的<<Refactoring—Improving the Design of Existing Code>>一書中談到了為何重構的幾點原因:

          1. 重構可以改進軟件設計

          如果不進行重構,程序的設計會變得越來越糟糕。通常程序員只為短期的目的,或者在沒有完全理解整體設計的時候,就開始修改代碼,這樣程序將會逐漸失去自己的結構,程序員也愈來愈難通過閱讀源碼理解原本設計,相信對此每一個開發人員都深有體會。

          代碼結構的流失是累積性的,愈難看出代碼所代表的意思,就越難保護其中的設計,于是設計也將變得越來越糟糕,經常性重構可以幫助維持設計該有的形態。

          2. 重構使軟件更易被理解

          很多開發人員認為代碼只要能夠運行起來就可以了,筆者剛開始做開發的時候也是這么認為的,也寫過很多的垃圾代碼,也因此吃了不少苦頭。

          也許有些人可能會認為自己可能不久就會離開所在的職位,不必在意代碼的質量,但作為一個開發人員來說,寫出漂亮的代碼是最基本的素質。

          在軟件的不斷修改過程中,代碼的可讀性越來越差也是會慢慢累積的,但這不要緊,只要記得持續重構,就能使自己的代碼更容易被理解。

          3. 重構可以協助找到Bugs

          對代碼的理解,可以更容易找到bug,在重構的同時,也能夠更好的理解代碼及其行為,從而通過重構能夠幫助開發人員寫出更強壯的代碼。

          4. 重構可以提高編程的速度

          良好的設計是快速軟件開發的根本,如果沒有良好的設計,也許開始的一段時間開發人員的進展迅速,但是惡劣的設計很快就會使開發速度慢下來。也許把時間花在調試上的時間會越來越多,修改的時間會越來越長,而且這會是一個惡性的循環。
          良好的設計是維持軟件開發速度的根本,重構可以幫助開發人員更快速地開發軟件,因為它能夠阻止系統的設計變質,能夠提高代碼的可讀性。

          使用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”重構相反,它能夠從冗長的方法中提取小的方法,把大的方法分解成多個小方法來實現,通過此重構能夠使代碼看上去更簡單漂亮,也很大程度上提高代碼的復用性??梢赃x擇要提取方法的代碼,在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能夠解決所有重構的問題,有些時候手動重構還是必須的。自動重構的理念應該是“工具輔助下的重構工作”,但開發人員仍然承擔很大一部分重構工作。

           

          posted @ 2011-11-15 10:30 夢晴 閱讀(327) | 評論 (0)編輯 收藏

          僅列出標題  
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿

          隨筆檔案

          搜索

          最新評論

          主站蜘蛛池模板: 和平县| 罗城| 桂东县| 仁寿县| 永登县| 精河县| 汕头市| 西藏| 安图县| 光泽县| 崇文区| 抚远县| 武胜县| 锦屏县| 祁连县| 视频| 莆田市| 宜春市| 连江县| 甘孜| 新营市| 台南市| 江安县| 绥中县| 临泽县| 修武县| 常州市| 苗栗市| 封丘县| 榆树市| 英德市| 阿勒泰市| 峨眉山市| 阿鲁科尔沁旗| 如皋市| 神农架林区| 翼城县| 朝阳县| 北碚区| 九龙坡区| 商洛市|