熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

在Eclipse中創建新的重構功能(組圖)

2013-11-23 20:42:50  來源: Java開源技術 

   介紹
  
  重構在現代軟件開發過程中扮演著重要的角色它能夠減輕軟件開發人員的工作負擔提高軟件開發的生產效率為了闡明重構的重要性我們在這裡引用了developerWorks上David Carew提供的關於重構的教程中的一段話
  
  現在一個開發者的工作大部分在於對現有的代碼進行修改而不是起草寫新的代碼簡單的修改可能包括對現有代碼進行添加然而多樣化的修改或擴展的改變會使軟件內部結構開始惡化重構改變軟件的內部結構使得軟件更容易理解並且在不需要改變其顯著的行為的情況下使得修改的代價也更小
  
  在Java軟件開發過程中通過使用Eclipse提供的重構工具我們至少獲得了以下好處
  
   最終產品更為健壯我們對程序代碼的修改將不太可能出錯出現遺漏修改的可能變少即使出現問題也能夠通過Undo功能回退到重構前的狀態
  
   提高了生產效率通常一次重構能夠完成對程序代碼的多處改動最為明顯的例子可能是Eclipse提供的Rename重構它能夠在修改名稱的同時相應的更改所有的引用
  
  Eclipse為我們提供了多種實用的重構功能在軟件開發過程中使用這些重構能夠給我們帶來極大的好處然而針對每個開發人員的特殊需要總有一些迫切需要的功能是不能通過已有的重構來獲得的這個時候我們可以對Eclipse平台進行一些擴展創建適應我們自己需要的重構如果這個重構恰好能夠符合大多數人的需要我們也可以像其他Eclipse的contributor一樣將我們的重構貢獻給Eclipse社區
  
  接下來我們將通過一個例子來展示如何在Eclipse中創建新的重構功能我們這裡創建的重構將用於遷移JUnit的測試用例我們知道在當前版本的JUnit中一個用於測試的函數必須以字符串test作為方法名稱的開始而在即將來到的JUnit 一個@Test的Annotation被用於標明方法是一個測試方法我們將要創建的重構將完成這個遷移工作即在所有的以test開始的方法之前加上@Test標記@Test Annotation還可以包含一個timeout屬性用來規定方法的最大執行時間我們在向導中提供了一個頁面供用戶選擇是否需要timeout屬性
  
   結果預覽
  
  為了給讀者一個直觀的感受我們下面首先介紹本文中例子的實際運行效果在閱讀完本文之後讀者朋友也能夠順利的完成類似的功能
  
  啟動例子程序提供的Refactor之後我們獲得了一個由三個頁面組成的向導在第一個頁面中用戶可以選擇是否需要timeout參數並且用戶能夠設置timeout參數的值
  
  
輸入參數
   

  當用戶輸入參數完畢之後通過單擊Next按鈕我們將進入下一個頁面向導將進行初始條件檢查和最終條件檢查並將檢查的結果反饋給用戶在圖 中我們可以看到初始條件和最終條件都正常因此我們可以進入下一步
  
  
顯示條件檢查
   

  接下來是預覽窗口(圖 向導用直觀的界面顯示了在應用向導之後我們將會對源代碼造成怎樣的改動用戶可以在這個頁面中判斷最終的修改是否符合自己的需要另外用戶也能夠選擇性的取消對某些文件的修改
  
 

  當用戶檢查預覽頁面確認沒有問題之後用戶可以按下Finish按鈕從而完成重構這個時候源代碼會發生修改最後的結果如下所示
  
  清單
  
  package main;
  
  public class TestSomething {
  @Test(timeout=)
  public void testSomething(){
  
  }
  }
  
   總體結構和流程
  
  在Eclipse中一個重構操作主要由以下三個部分組成
  
   RefactoringWizard類RefactoringWizard提供了向導式的用戶界面來引導用戶完成重構工作不需要我們做任何工作Eclipse已經通過RefactoringWizard為我們提供了預覽頁面條件檢查頁面以及Undo/Redo等功能我們需要繼承這個類從而為重構過程提供特定的用戶界面
  
   Refactoring類Refactoring類完成具體的定位和修改代碼功能為了建立新的Refactoring我們需要繼承這個類並實現重構的邏輯部分
  
   AST和ASTParser在Refactoring類中我們需要對代碼進行定位和修改這可以通過AST機制來完成AST是abstract syntax tree的簡稱它能夠將Java代碼解析成為一個樹形結構在利用了AST樹之後對源代碼的修改變成了對AST樹的遍歷更改節點屬性以及插入和刪除節點等
  
  一個典型的重構操作流程如下所示
  
   用戶選擇要進行重構的對象通過菜單項或按鈕啟動重構操作
  
   創建具體的Refactoring類彈出RefactoringWizard
  
   RefactoringWizard與用戶交互引導用戶輸入必要的參數RefactoringWizard調用Refactoring類的函數進行條件檢查
  
   Refactoring類創建AST並利用其對源代碼進行定位和修改這裡進行的修改並不直接應用到源代碼上而是被保存成Change對象供Refactoring框架使用
  
   RefactoringWizard調用Refactoring類的函數獲得重構內容的詳細描述信息(即第步生成的Change對象)顯示在預覽界面上待用戶確認
  
   用戶確認後Refactoring框架將修改代碼重構操作結束
  
  接下來我們將詳細介紹新建重構類型的各個步驟
  
   創建插件工程
  
  在大家對整個系統構架有了一個大概的了解之後我們的介紹就從創建工程開始大家都知道Eclipse提供了很好的擴展性通過創建插件就能把我們要添加的重構功能無縫的插入到Eclipse平台中創建插件工程的方法在很多地方都有介紹這裡不再詳細講解如果需要基礎的插件開發知識我們可以參考《 開發 Eclipse 插件》樹立基本的插件開發意識
  
  通過菜單 File > New> Project選擇Plugin Project點擊Next出現對話框輸入項目名稱manageannotation接受其他選項的默認值點擊Next出現插件屬性設置的對話框繼續接受默認值點擊Next出現選擇插件模板對話框該工程要在Refactor菜單中添加一個新的菜單項所以這裡我們采用HelloWorld的插件模板點擊Next修改Action類名稱的值為AnnotationManageAction點擊Finish按鈕至此一個最基本Eclipse工作台的插件工程就被創建出來了
  
  插件工程創建後缺省進入Plugin開發透視圖Plugin Manifest編輯器自動打開顯示這個插件工程的基本信息如對其他插件的依賴擴展點構建(build)的配置信息等等由於該工程需要用到其他插件的功能必須為其添加到其他插件的依賴在Plugin Manifest編輯器點擊Dependencies頁面在該頁面中的Required Plugins列表中通過Add按鈕添加如下的插件
  
  清單
  
  orgeclipsejfacetext
  rerefactoring
  orgeclipseltkuirefactoring
  orgeclipsejdt
  re
  
  或者也可以通過直接修改MANIFESTMF文件完成操作完成後察看MANIFESTMF文件注意RequireBundle列表中是否出現了新添加的這幾項MANIFESTMF文件如下
  
  清單
  
  ManifestVersion:
  BundleManifestVersion:
  BundleName: Annotation Plugin
  BundleSymbolicName: manageannotation; singleton:=true
  BundleVersion:
  BundleActivator: manageannotationAnnotationPlugin
  BundleLocalization: plugin
  RequireBundle: orgeclipseui
  reruntime
  orgeclipsejfacetext
  rerefactoring
  orgeclipseltkuirefactoring
  orgeclipsejdt
  re
  EclipseAutoStart: true
  
  在Plugin Manifest編輯器中打開插件清單文件pluginxml可以看到這個插件擴展了orgeclipseuiactionSets擴展點這是一個基本的Eclipse工作台的擴展點通過擴展它插件可以很簡單得對Eclipse的菜單工具條進行擴展這個pluginxml是HelloWorld插件模板的清單文件我們把它改成適合這個工程的文件清單如下
  
  清單
  
  <?xml version= encoding=UTF?>
  <?eclipse version=?>
  <plugin>
  
  <extension
  point=orgeclipseuiactionSets>
  <actionSet
  label=Annotation Action Set
  visible=true
  id=manageannotationactionSet>
  <menu
  label=%nulabel
  path=source
  id=orgeclipsejdnu>
  <separator name=reorgGroup/>
  </menu>
  <action
  class=manageannotationactionsAnnotationManageAction
  icon=icons/samplegif
  id=manageannotationactionsAnnotationManageAction
  label=%Annotationmanage
  menubarPath=orgeclipsejdnu/reorgGroup
  toolbarPath=reorgGroup
  tooltip=Manage Annotation in Java Project/>
  </actionSet>
  </extension>
  </plugin>
  
  該清單文件表明在Refactor菜單中添加了一個新菜單項Annotation Manage並在工具條上相應添加了一個按鈕點擊菜單項或者按鈕的事件由類manageannotationactionsAnnotationManageAction處理
  
  最後需要修改的就是manageannotationactionsAnnotationManageAction類它繼承了orgeclipseuiIWorkbenchWindowActionDelegate接口該接口用於處理各種通過擴展點添加的操作當菜單項或者按鈕被點擊時這個類就被Eclipse工作台裝載進來處理轉發過來的請求以及接下來的操作
  
  AnnotationManageAction被創建後一旦用戶的選擇部分有所改變接口的selectionChanged函數就會被觸發告知用戶所選擇的部分可以在這個函數中根據用戶的選擇相應的修改操作的可用性或者其他顯示屬性例如在本文的工程中我們希望只有當用戶選擇了一個Java模型元素時才能使用這個操作那麼就需要在selectionChanged中添加如下的代碼
  
  清單
  
  public void selectionChanged(IAction action ISelection selection) {
  if (selectionisEmpty())
  select = null;
  else if (selection instanceof IStructuredSelection) {
  IStructuredSelection strut = ((IStructuredSelection) selection);
  if (strutsize() != )
  select = null;
  if (strutgetFirstElement() instanceof IJavaElement)
  select = (IJavaElement) strutgetFirstElement();
  } else
  select = null;
  
  actionsetEnabled(select != null);
  }
  
  selectionChanged函數的參數selection記錄了用戶選擇的部分我們首先判斷它的選擇部分的數目是否為一然後判斷這個唯一的選擇部分是否為Java模型元素這兩個條件任何一個不滿足都會導致actionsetEnabled(false)的執行這時會彈出如下的對話框說明操作不可用同時菜單項和按鈕都會顯示成灰色直到用戶選擇了合適的部分時菜單項和按鈕才會實顯就可以進行具體的操作了
  
  
表明Action目前不能執行的對話框
   educitycn/img_///jpg >

  操作的執行是在AnnotationManageAction的run函數中實現的例如在本文的工程中就是彈出RefactoringWizard對話框指導用戶完成重構的工作這些我們將在下面的章節中講述
  
   擴展Refactoring類
  
  通過前面系統構架的介紹大家知道了Refactoring和RefactoringWizard是完成EClipse重構功能的基礎類在創建好插件工程後我們就通過擴展Refactoring來實現具體的功能
  
  Refactoring是所有支持代碼轉化的類的抽象父類它在整個流程中與RefactoringWizard交互以完成重構的功能起著非常重要的作用這些類需要提供以下兩類方法
  
  用於條件檢查的方法判斷重構操作大體而言能否執行以及具體的轉化能否完成創建Change對象的方法Change對象描述了所有將要執行的對當前代碼的修改操作
  
  Refactoring類的典型流程如下所示
  
   具體的Refactoring類被創建
  
   獲得用戶選擇的要進行重構的對象初始化該Refactoring類這個由具體的實現類給出相應的方法
  
   在重構操作開始執行時首先調用Refactoring的checkInitialConditions(IProgressMonitor) 基於用戶選擇的對象做一個的初始檢查這個通常由界面自動執行返回RefactoringStatusFATAL表明初始檢查沒有通過重構操作不能繼續
  
   獲得進行重構的其他參數比如對重命名操作來說就是指新名字這個通常是由界面根據用戶的輸入提供的由具體的實現類給出相應的方法
  
   獲得用戶輸入參數後調用Refactoring的checkFinalConditions(IProgressMonitor)進行剩下的檢查這個通常由界面自動執行返回RefactoringStatusFATAL表明最後的檢查沒有通過重構操作不能繼續
  
   調用Refactoring的createChange(IProgressMonitor)獲得Change對象這個通常由界面自動執行界面可以根據Change對象顯示預覽界面
  
  基於以上的介紹為了實現本文工程中的重構操作我們需要擴展Refactoring類為它增加一個構造函數並且具體實現checkInitialConditionscheckFinalConditions和createChange三個函數
  
  首先通過菜單File > New>Class彈出創建類的對話框輸入包名manageannotationrefactor類名AnnotationRefactoring輸入父類rerefactoringRefactoring選中繼承抽象方法復選框點擊完成按鈕一個擴展了Refactoring的最基本的類AnnotationRefactoring就被創建出來了
  
  首先為其增加構造函數以用戶選擇的Java模型元素作為參數Refactoring分析這個參數以得到所有相關的可寫Java文件作為重構操作的對象如果該模型元素包含在Java文件中則找到包含它的文件節點如果該模型元素包含Java文件則找到它的所有子Java文件構造函數代碼如下
  
  清單
  
  public AnnotationRefactoring(IJavaElement element) {
  while (elementgetElementType() > IJavaElementCOMPILATION_UNIT) {
  element = elementgetParent();
  if (element == null)
  return;
  }
  if (elementgetElementType() == IJavaElementCOMPILATION_UNIT) {
  if (!elementisReadOnly())
  compilationUnitsadd(element);
  }
  if (elementgetElementType() < IJavaElementCOMPILATION_UNIT)
  findWritableCompilationUnits(element);
  }
  
  接著完成checkInitialConditions函數實現初始檢查的具體操作作為示例在本文工程中我們不進行任何具體的檢查操作只簡單得給出初始檢查成功的信息返回RefactoringStatus
  
  INFO以使重構操作繼續執行checkInitialConditions函數代碼如下
  
  清單
  
  public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
  throws CoreException OperationCanceledException {
  return RefactoringStatuscreateInfoStatus(Initial Condition is OK!);
  }
  
  接著完成checkFinalConditions函數實現獲得用戶輸入參數後的後續檢查操作在本文工程中我們首先收集所有需要添加注釋的以test開頭的方法判斷是否不存在這樣的方法如果不存在給出出錯信息返回RefactoringStatusFATAL以結束重構操作如果存在這樣的方法則給出後續檢查成功的信息返回RefactoringStatus
  
  INFOcheckFinalConditions函數代碼如下
  
  清單
  
  public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
  throws CoreException OperationCanceledException {
  collectChanges();
  if (fChangeManagersize() == )
  return RefactoringStatus
  createFatalErrorStatus(No testing methods found!);
  else return RefactoringStatuscreateInfoStatus(Final condition is OK!);
  }
  
  最後創建Change對象的createChange函數是整個重構操作中最核心的代碼它的實現將在下面章節中介紹
  
   使用AST構造Change對象
  
  當我們找到了修改的位置時我們有兩個選擇
  
   通過IScanner接口掃描代碼然後通過IBuffer接口直接修改代碼
  
   通過遍歷和編輯AST樹進行結構化的修改
  
  DeveloperWorks提供的文章《擴展Eclipse的Java開發工具》中給出了使用IBuffer接口的例子現在我們要講述使用AST來遍歷和修改Java源代碼的方法
  
  AST是abstract syntax tree的縮寫它是Eclipse中的Java開發環境(JDT)為我們提供的極為強大的源代碼解析和編輯工具
  
  在使用AST樹提供的功能之前我們首先要創建AST樹由於AST樹的構建是一項費時的操作JDT缺省情況下不將源代碼解析為AST樹下面的代碼演示了獲得一個ICompilationUnit對應的AST樹的過程在JDT提供的API中ICompilationUnit接口用於表示一個可以被編譯的源代碼文件在我們提供的例子程序中我們通過下面的代碼將整個文件解析成為了一顆AST樹
  
  清單
  
  ASTParser parser = ASTParsernewParser(ASTJLS);
  parsersetSource(cu);
  ASTNode root = parsercreateAST(null);
  
  AST樹中的每個節點都是ASTNode類型通過Visit模式我們可以訪問一個ASTNode包含的所有節點下面的代碼演示了訪問一個AST節點並獲得其中所有的MethodDeclaration節點的方法
  
  清單
  
  private void getMethods(ASTNode cuu final List methods) {
  cuuaccept(new ASTVisitor() {
  public boolean visit(MethodDeclaration node) {
  methodsadd(node);
  return false;
  }
  });
  }
  
  在收集到了所有的MethodDeclaration節點之後我們就可以通過向AST樹中插入和刪除節點或者修改已有的節點的方法來修改AST樹了下面的代碼演示了使用AST工具為方法添加@Test Annotation的功能
  
  清單
  
  private boolean collectChanges(CompilationUnit root
  MethodDeclaration method) {
  if (methodgetName()getFullyQualifiedName()startsWith(test)) {
  AST ast = methodgetAST();
  if (needTimeout) {
  NormalAnnotation na = astnewNormalAnnotation();
  nasetTypeName(astnewSimpleName(Test));
  MemberValuePair pair = astnewMemberValuePair();
  pairsetName(astnewSimpleName(timeout));
  pairsetValue(astnewNumberLiteral());
  navalues()add(pair);
  methodmodifiers()add( na);
  } else {
  MarkerAnnotation na = astnewMarkerAnnotation();
  nasetTypeName(astnewSimpleName(Test));
  methodmodifiers()add( na);
  }
  return true;
  }
  return false;
  }
  
  在Refactoring框架中我們要求對AST樹的修改並不立刻反映到源代碼中相反我們需要一個能記錄整個修改過程的Change對象Refactoring框架將利用這個Change對象來顯示Priveiw窗口進行Undo和Redo等操作大致上我們記錄對一個AST樹的修改從而生成Change對象的過程如以下代碼所示
  
  清單
  
  rootrecordModifications();
  
  //在這裡修改AST樹…
  
  TextEdit edits = rootrewrite(document cugetJavaProject()
  getOptions(true));
  TextFileChange change = new TextFileChange( (IFile) cu
  getResource());
  changesetEdit(edits);
  
  最後由於Refactoring類的createChange方法僅返回一個Change對象如果我們需要對多個源代碼文件進行修改我們可以利用CompositeChange類將多個Change對象封裝成一個Change對象這個過程可能類似如下代碼所執行的流程
  
  清單
  
  public Change createChange(IProgressMonitor pm) throws CoreException
  OperationCanceledException {
  Change[] changes = new Change[fChangeManagersize()];
  Systemarraycopy(fChangeManagertoArray() changes
  fChangeManagersize());
  CompositeChange change = new CompositeChange(
  Add @Override Annotation changes);
  return change;
  }
  
   擴展RefactoringWizard 框架
  
  Eclipse中的RefactoringWizard框架擴展了Eclipse的Wizard框架關於Wizard框架的介紹可以在Eclipse的幫助系統中找到這裡我們僅從OO設計和架構的角度探討一下RefactoringWizard框架
  
  我們從Wizard相關的幾個類開始
  
   WizardPage類
  
  WizardPage是一個包含了多個界面元素(比如文本框Text按鈕Button)的一個界面組合部分各個Page之間是獨立的是可以動態加載的WizardPage類的職責有
  
  組合SWT界面元素構造出一個界面頁
  
  定義本身界面元素的操作行為
  
  在RefactoringWizard框架中預設了兩個通用的屬性頁PreviewWizardPage和ErrorWizardPagePreviewWizardPage類是用來預覽重構後的修改對比代碼或其他資源的變化ErrorWizardPage類是用來處理條件檢查及錯誤狀態通知的我們只需擴展RefactoringWizard框架就可以自動獲取這兩項強大的功能
  
   Wizard類
  
  一個Wizard就是一個裝載一系列WizardPage頁的容器Wizard類的職責有
  
  裝載一系列WizardPage構造出一個復雜的界面
  
  裝載領域類來處理具體業務邏輯(在RefactoringWizard框架中這個類就是Refactoring類)
  
  維護WizardPage頁之間以及頁與領域類之間的數據傳遞和狀態共享(在這裡要補充一點其實在具體RefactoringWizard框架的實現中有專門的類來分擔這部分職責
  
  我們的界面行為可以千變萬化(通過組合不同的WizardPage)而負責處理業務邏輯的領域類也可以獨立的變化你可以隨意擴展Wizard的界面功能(-對擴展開放)而不用修改現有RefactoringWizard框架(-對修改封閉)這正是OO設計的最基本原則-OCP(OpenClose Principle)
  
   WizardDialog類
  
  這個對話框類的主要職責是構造一個完整的GUI界面以及操作界面它預設了一些按鈕(BackNextFinishCancel)等界面元素它負責裝載Wizard類操作時通過按鈕BackNext來在多個WizardPage之間切換
  
  下面我們給出RefactoringWizard框架的架構圖
  
  
Refactoring Wizard架構圖
   educitycn/img_///gif >

  從圖 中我們可以看到如果我們把每一個WizardPage頁看作一項業務那麼Refactoring正是處理業務邏輯的控制中心它封裝了所有對業務邏輯的處理當然它可以在將處理任務委任出去但請注意它並不負責實現業務流程也就是說各業務(各個Page界面)之間的邏輯順序關系不由它維護
  
  RefactoringWizard框架充分考慮到了應用的可擴展性它在SWT的MVC(模型-視圖-控制)元架構模式的基礎上添加了一些新的架構元素MVC模式促使業務邏輯與界面分離界面與控制行為分離而RefactoringWizard框架增強了界面本身分離的特性它將一個完整的界面分拆成多個頁面用戶可以動態組合這些頁面或添加新的頁面來擴展界面行為這種特性-界面的動態組合低耦合高內聚封裝良好的接口-讓我們領略到了OO設計的精髓
  
  下面我們通過以下幾個步驟來擴展RefactoringWizard框架
  
  擴展RefactoringWizardPage
  擴展RefactoringWizard
  啟動RefactoringWizard
  
  第一步擴展RefactoringWizardPage首先我們新建一個類AnnotationRefactoringWizardPage它需要繼承UserInputWizardPage類(其父類是RefactoringWizardPage而RefactoringWizardPage最終實現了IDialogPage接口)接下來就是實現IDialogPage接口的createControl(…)方法在這個方法裡實現你的界面行為比如我們例子中的TimeOut文本框代碼清單如下
  
  清單
  
  /**
  * create composite to add UI elements
  */
  public void createControl(Composite parent) {
  // define UI
  Composite composite = new Composite(parent SWTNONE);
  GridLayout lay = new GridLayout();
  laynumColumns = ;
  compositesetLayout(lay);
  
  btnCheck = new Button(composite SWTCHECK);
  btnChecksetText(Add timeout parameter);
  GridData gdBtnCheck = new GridData();
  gdBtnCheckhorizontalSpan = ;
  gdBtnCheckhorizontalAlignment = GridDataFILL;
  btnChecksetLayoutData(gdBtnCheck);
  
  labName = new Label(composite SWTWRAP);
  labNamesetText(TimeOut:);
  GridData gdLabName = new GridData();
  gdLabNamehorizontalAlignment = GridDataBEGINNING;
  gdLabNamegrabExcessHorizontalSpace = true;
  labNamesetLayoutData(gdLabName);
  
  txtTimeOut = new Text(composite SWTSINGLE | SWTBORDER);
  GridData gdTxtTimeOut = new GridData();
  gdTxtTimeOuthorizontalAlignment = GridDataEND;
  gdLabNamegrabExcessHorizontalSpace = true;
  txtTimeOutsetLayoutData(gdTxtTimeOut);
  txtTimeOutsetText();
  
  // init status
  labNamesetEnabled(false);
  txtTimeOutsetEnabled(false);
  // add listener
  defineListener();
  
  // 將composite納入框架的控制
  setControl(composite);
  DialogapplyDialogFont(composite);
  }
  
  在這裡我們要特別注意的一點是在定義完我們的界面元素後需要將自定義的Composite納入框架的控制就是這行代碼setControl(composite);
  
  在我們處理完輸入數據檢查後進入下一頁面之前我們需要設置頁面完成的狀態以及傳遞輸入數據到領域類Refactoring我們用以下代碼設置好頁面完成的狀態後下個頁面ErrorWizardPage就會處理顯示邏輯
  
  清單
  
  private void notifyStatus(boolean valid String message) {
  //設置錯誤信息
  setErrorMessage(message);
  //設置頁面完成狀態
  setPageComplete(valid);
  }
  
  傳遞輸入數據通過以下代碼來處理
  
  清單
  
  private void setRefactoring(boolean selection String text) {
  AnnotationRefactoring refactoring = (AnnotationRefactoring) getRefactoring();
  refactoringsetNeedTimeout(true);
  if(selection) {
  refactoringsetTimeout(IntegervalueOf(txtTimeOutgetText())intValue());
  }
  }
  
  其中getRefactoring()方法是繼承自RefactoringWizardPage的方法由於我們的RefactoringWizard類裝載了RefactoringWizardPage和Refactoring類這個方法是從RefactoringWizard類中獲得的這裡面用到了Observer設計模式至此我們完成RefactoringWizardPage的擴展
  
  第二步擴展RefactoringWizard首先我們新建一個類AnnotationRefactoringWizard它需要繼承RefactoringWizard類這個類中我們只需要加載定義好的AnnotationRefactoringWizardPage類和AnnotationRefactoring類當然復雜的處理已經有RefactoringWizard框架處理好了下面我們在構造函數中加載Refactoring類
  
  清單
  
  public AnnotationRefactoringWizard(Refactoring refactoring) {
  super(refactoring WIZARD_BASED_USER_INTERFACE);
  }
  
  然後我們加載我們的AnnotationRefactoringWizardPage類只需重載父類RefactoringWizard的addUserInputPages()方法就可以
  
  清單
  
  protected void addUserInputPages() {
  page = new AnnotationRefactoringWizardPage(refactor annotation);
  addPage(page);
  }
  
  第三步啟動RefactoringWizard擴展好RefactoringWizard之後就需要在用戶點擊菜單項或是按鈕時彈出這個對話框RefactoringWizard最好使用RefactoringWizardOpenOperation類來打開(當然也可以用RefactoringWizardDialog)RefactoringWizardOpenOperation首先進行重構的初始檢查通過後才打開RefactoringWinzard對話框否則就會打開錯誤對話框前面完成創建插件工程時我們提到彈出RefactoringWizard對話框的代碼應該放到響應菜單操作的類的run函數中具體到本文工程中就是把下面的代碼放到AnnotationManageAction的run函數中這些代碼首先依次構造Refactoring和RefacoringWizard子類AnnotationRefactoring和AnnotationRefactoringWizard並將AnnotationRefactoring的引用傳遞給AnnotationRefactoringWizard然後用RefactoringWizardOpenOperation打開AnnotationRefactoringWizard彈出向導對話框
  
  清單
  
  public void run(IAction action) {
  Shell shell = windowgetShell();
  
  AnnotationRefactoring refactor = new AnnotationRefactoring(select);
  AnnotationRefactoringWizard wizard = new AnnotationRefactoringWizard(
  refactor);
  RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(
  wizard);
  try {
  oprun(shell Inserting @Override Annotation);
  } catch (InterruptedException e) {
  eprintStackTrace();
  }
  }
  
   小結
  
  在Eclipse中有效的利用重構能夠大大的減輕軟件開發人員的工作負擔提高軟件的健壯性然而目前重構仍然處在一個工具缺乏的時代以Eclipse為例只有JDT提供的重構工具最為完善而針對其他語言例如C++Python等的開發環境都缺乏對應的重構功能
  
  通過本文提供的方法我們能夠有效的利用Eclipse中的重構框架創建新的重構從而進一步提高已有開發環境的效率
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28943.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.