昨天的那个动态代理的UML类图还不够全面,在TFooInvHandler实现中并不是直接通过RTTI操作TFooImpl的,而是通过一个通用的RTTI Invoke实现类:TInvoker进行。FImpl作为TInvoker的构造子参数传入,TInvoker通过接口取得VTAB,然后进行Dispatch操作,这个实现是可以独立出来的通用操作。
这样的话,在Handler中的工作就很单纯了,就是实现Aspect。
昨天临下班前,令狐向我指出一个在编译语言中不好解决的问题:Invoke的Context。Aspect除了需要Invoke时的那些如接口,方法,参数,返回值等内容以外,还需要一些额外的内容,对于这些额外内容的处理将最终导致问题不可避免的复杂化。这对动态语言来说可能不成问题,但对于静态语言,这是一件可能导致过多不必要耦合的陷阱。
所以我昨天下班回去后又研究了一下。最后我想还是将问题尽可能地简单化比较好,Aspect所需要的Context还是由Aspect自己维护,DynamicProxy不提供这方面的义务,以尽可能避免不必要的侵入。
在研究完TInvContext的实现后,我决定还是就用它了,因为有现成的代码提供了对不同的调用约定的处理(比如Cdecl/Pascal/StdCall等),自己实现太麻烦了。但如果可能的话,我还是想同时提供一个转换机制,用于生成一个Variant动态数组的参数,以简化使用。
继续关注一下。嘿嘿。