通過了一番討論我們一致認為這個應該用AOP的思想來解決但怎樣在Delphi中來實現AOP呢修改整個程序框架是不可能的我們只能在現有的基礎上做
正當我們要放棄的時候突然想到了一個突破點日志中記錄的功能在程序實現的時候全部使用Action組件來做的是否可以考慮在Action上面做文章呢?
曙光啊曙光!
解決方式——瞞天過海
通俗點理解AOP就是將一段代碼統一插入某一類地方但像Delphi這樣的語言是很難實現插入代碼的這一功能不過我們可以通過事件機制來實現同樣的效果
Action的執行代碼都寫在事件OnExecute中如果能在執行事件之前和之後執行我想要的動作是不是就可以解決了?
procedure TModuleacActionExecute(Sender: TObject);
begin
// do something
end;
procedure TActionHookReGISterAction(Action: TAction);
begin
// 記錄Action與原始的OnExecute事件
FActionListAdd(Action);
SetLength(FActionEvents Length(FActionEvents) + );
FActionEvents[High(FActionEvents)] := ActionOnExecute;
// 瞞天過海偷換事件
ActionOnExecute := HookActionExecute;
end;
procedure TActionHookHookActionExecute(ASender: TObject);
begin
DoBeforeActionExecute(TAction(ASender));
// 觸發原始事件
FActionEvents[FActionListIndexOf(ASender)](ASender);
DoAfterActionExecute(TAction(ASender));
end;
procedure TActionHookDoAfterActionExecute(Action: TAction);
begin
// 所有的Action執行完畢後調用此處
FLogLogCommand(ActionCaption);
end;
相關的UML圖如下
圖略
采用這樣的方式後很明顯我們不需要將日志相關代碼分散到系統的各個地方只需要在一個統一的地方將所有Form上的Action組件注冊到TActionHook中就可以了
擴展思考
在Delphi中可以通過事件的機制實現代碼注入技術當然同樣在其他支持事件的語言中也可以實現相比之下這種方法實現AOP比較簡單並且不需要在系統的整體結構上作什麼調整完全通過語言層面支持
例子中針對Action的組件來處理日志功能將TActionHook擴展之後可以將其他的控件操作也通過這套機制記錄到日志中
很多同行們都埋怨自己做的是體力活沒什麼技術含量同樣在剛開始的時候我也認為這個任務是體力活但是如果我們能勤於思考新的解決方法體力活絕對能夠變為技術活只有這樣才能不辜負高科技這個美譽啊
上面介紹的方法肯定不是最好的這次拿出來和大家分享一方面是將自己的經驗獻給需要的朋友另外也特別希望大家能給一點好的建議一起交流共同學習
[] []
From:http://tw.wingwit.com/Article/program/Delphi/201311/24868.html