通过了一番讨论我们一致认为这个应该用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扩展之后可以将其他的控件操作也通过这套机制记录到日志中
很多同行们都埋怨自己做的是体力活没什么技术含量同样在刚开始的时候我也认为这个任务是体力活但是如果我们能勤于思考新的解决方法体力活绝对能够变为技术活只有这样才能不辜负高科技这个美誉啊
上面介绍的方法肯定不是最好的这次拿出来和大家分享一方面是将自己的经验献给需要的朋友另外也特别希望大家能给一点好的建议一起交流共同学习
[] []