在MVC模式裏controller處於一個核心的位置,它要負責接受從view發來的用戶交互請求,將用戶請求轉發給商業對象進行處理,然後從商業對象獲取處理結果,選擇合適的視圖呈現給用戶。
也即controller有
- 監聽view的用戶操作並及時響應
- 調用model進行用戶的交互信息處理,然後將處理結果以恰當的方式(對話框,或者新的視圖等)呈現給用戶。
如何監聽view的操作?在delphi的VCL控件裏封裝了很多的事件,我們需要在controller裏處理這些事件,然後在創建view時,把事件方法賦值給view裏的控件,就實現了監聽用戶操作的功能。例如TInfoManagementView裏有button->New,我們在controller裏提供button的onclick方法(這是一個TNotifyEvent類型的事件方法),然後在TController.getInfoManagementView方法裏將這個實現賦值給NewButton.OnClick = newClick即可。
至於調用model來處理用戶請求,基礎的工作就是在上述的監聽事件裏創建model實例,然後將用戶輸入更新到這個model實例,調用model相應的方法進行處理,獲取處理結果即可。還是以New Button爲例,我們在響應New Button的click事件時,首先調用getInfoEditView來爲用戶提供一個空白的信息輸入界面(這裏還沒有設計到model),然後當用戶輸入完畢點擊button Save提交,在controller.saveClick方法裏,我們需要new一個model,然後將用戶輸入更新到model上,然後調用model.save保存至數據庫。如果沒有出錯,就彈出一個“保存成功!”的提示框,用戶點擊“確定”或計時結束後回到managementView;如果保存失敗,就彈出具體的錯誤信息,並保留在EditView上。
根據以上邏輯,controller的實現聲明可以如下:
TController = class
private
FModel: IModel;
FManagementViewClass: TInfoManagementViewClass;
FInfoEditViewClass: TInfoEditViewClass;
procedure newButtonClick(Sender: TObject);
procedure saveButtonClick(Sender: TObject);
public
procedure showManagementView(parent: TWinControl);
procedure showEditView(Mode: TInfoMode);
end;
implemention
procedure TController.newButtonClick(Sender: TObject);
begin
with getEditView do
try
FModel := TModelFactory.getModelClass(className).create;
InfoMode := ifmdNew;
saveButton.onClick := saveClick;
if ShowModal = mrOK then
refreshList;
finally
FModel.free;
free;
end;
end;
procedure TController.saveButton(Sender: TObject);
begin
updateModel;
try
DBHelperFactory.getDBHelper.startTrans;
FModel.save;
DBHelperFactory.getDBHelper.commitTrans;
exception
on e: exception do
begin
DBHelperFactory.getDBHelper.rollbackTrans;
showmessage(e.message);
end;
end;
end;
procedure TController.showManagementView(parent: TWinControl);
var
view: TInfoManagementView;
begin
view := FManagementViewClass.create(parent);
if not assigned(parent) then
begin
view.showModal;
end
else
begin
view.parent := parent;
view.ManualDock(parent);
view.show;
end;
end;
procedure TController.showEditView(Mode: TInfoMode);
begin
with FInfoEditViewClass.Create(nil)
try
model := FModel;
InfoMode := Mode;
finally
free;
end;
end;
這樣controller也搭建起來了;MVC模式就成爲一個完整的框架。
controller的基礎實現已經有了,但是我們不能也不應該在mainView(即主操作界面)裏引用所有的controller,那末要如何實現呢?我們需要提供一個controllerFactory,mainView只需要知道controller的名稱(不需要知道具體的controller類型),通過調用controllerFactory.getController(controllerName)即可獲取到一個相應的controller實例。mainView又如何知道controller的名稱呢,這就是mainController需要乾的事情了。這涉及到具體的mainController實現邏輯,就不再累述了。