擴展RefactoringWizard 框架
Eclipse中的RefactoringWizard框架擴展了Eclipse的Wizard框架
關於Wizard框架的介紹可以在Eclipse的幫助系統中找到
這裡我們僅從OO設計和架構的角度探討一下RefactoringWizard框架
我們從Wizard相關的幾個類開始
WizardPage類 WizardPage是一個包含了多個界面元素(比如文本框Text
按鈕Button)的一個界面組合部分
各個Page之間是獨立的
是可以動態加載的
WizardPage類的職責有
·組合SWT界面元素
構造出一個界面頁
·定義本身界面元素的操作行為
在RefactoringWizard框架中預設了兩個通用的屬性頁
PreviewWizardPage和ErrorWizardPage
PreviewWizardPage類是用來預覽重構後的修改
對比代碼或其他資源的變化
ErrorWizardPage類是用來處理條件檢查及錯誤狀態通知的
我們只需擴展RefactoringWizard框架就可以自動獲取這兩項強大的功能
Wizard類 一個Wizard就是一個裝載一系列WizardPage頁的容器
Wizard類的職責有
·裝載一系列WizardPage
構造出一個復雜的界面
·裝載領域類來處理具體業務邏輯
(在RefactoringWizard框架中這個類就是Refactoring類)
維護WizardPage頁之間以及頁與領域類之間的數據傳遞和狀態共享
(在這裡要補充一點
其實在具體RefactoringWizard框架的實現中有專門的類來分擔這部分職責
)
我們的界面行為可以千變萬化(通過組合不同的WizardPage)
而負責處理業務邏輯的領域類也可以獨立的變化
你可以隨意擴展Wizard的界面功能(-對擴展開放)
而不用修改現有RefactoringWizard框架(-對修改封閉)
這正是OO設計的最基本原則-OCP(Open
Close Principle)
WizardDialog類 這個對話框類的主要職責是構造一個完整的GUI界面以及操作界面
它預設了一些按鈕(Back
Next
Finish
Cancel)等界面元素
它負責裝載Wizard類
操作時通過按鈕Back
Next來在多個WizardPage之間切換
下面我們給出RefactoringWizard框架的架構圖
圖 Refactoring Wizard架構圖 從圖
中我們可以看到
如果我們把每一個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
SWT
NONE);
GridLayout lay = new GridLayout();
lay
numColumns =
;
composite
setLayout(lay);
btnCheck = new Button(composite
SWT
CHECK);
btnCheck
setText(
Add timeout parameter
);
GridData gdBtnCheck = new GridData();
gdBtnCheck
horizontalSpan =
;
gdBtnCheck
horizontalAlignment = GridData
FILL;
btnCheck
setLayoutData(gdBtnCheck);
labName = new Label(composite
SWT
WRAP);
labName
setText(
TimeOut:
);
GridData gdLabName = new GridData();
gdLabName
horizontalAlignment = GridData
BEGINNING;
gdLabName
grabExcessHorizontalSpace = true;
labName
setLayoutData(gdLabName);
txtTimeOut = new Text(composite
SWT
SINGLE | SWT
BORDER);
GridData gdTxtTimeOut = new GridData();
gdTxtTimeOut
horizontalAlignment = GridData
END;
gdLabName
grabExcessHorizontalSpace = true;
txtTimeOut
setLayoutData(gdTxtTimeOut);
txtTimeOut
setText(
);
// init status
labName
setEnabled(false);
txtTimeOut
setEnabled(false);
// add listener
defineListener();
// 將composite納入框架的控制
setControl(composite);
Dialog
applyDialogFont(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();
refactoring
setNeedTimeout(true);
if(selection) {
refactoring
setTimeout(Integer
valueOf(txtTimeOut
getText())
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 = window
getShell();
AnnotationRefactoring refactor = new AnnotationRefactoring(select);
AnnotationRefactoringWizard wizard = new AnnotationRefactoringWizard(refactor);
RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
try {
op
run(shell
Inserting @Override Annotation
);
} catch (InterruptedException e) {
e
printStackTrace();
}
}
小結 在Eclipse中有效的利用重構能夠大大的減輕軟件開發人員的工作負擔
提高軟件的健壯性
然而
目前重構仍然處在一個工具缺乏的時代
以Eclipse為例
只有JDT提供的重構工具最為完善
而針對其他語言例如C++
Python等的開發環境
都缺乏對應的重構功能
通過本文提供的方法
我們能夠有效的利用Eclipse中的重構框架創建新的重構
從而進一步提高已有開發環境的效率
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28785.html