那么动态代理有什么用?
假设有下面这样一个接口及其实现: 【程序编程相关:如何判断一个机器的MSSQL是否启动 】
这要先从gof的proxy模式说起. 【推荐阅读:实现QQ窗体的缩入伸出功能 】
foo : ifoo;给你,其中foo指向tfooimpl的一个实例.现在你有了ifoo的定义,与这个foo实例--注意,你没有tfooimpl的定义与实现代码.如果现在要求你为所有的ifoo.dosth增加事务功能(假设dosth被实现为对数据库作更新操作),要怎么办? 【扩展信息:一个简单的,适应多种数据库之间存取操作的】
现在,如果你是这个接口的用户,而这个接口及其实现者提供了一个:
gof的proxy模式就是解决方案之一:
如果所示,首先要实现一个新的ifoo接口实现--tstaticproxy.其中用了一个属性fimpl记录了tfooimpl的实例.然后在 tstaticproxy中实现dosth与bar,并且将不需要变更的bar函数直接委托给fimpl处理,而在dosth的实现里加入事务处理即可. tstaticproxy的代码大致如下:
tstaticproxy = class( tinterfacedobject, iifoo ) private fimpl : ifoo; public constructor create( aimpl : ifoo ); function dosth( ... ) : xxx; function bar( ... ) : xxx; end; constructor tstaticproxy.create( aimpl : ifoo ); begin fimpl := aimpl; end; function tstaticproxy.dosth( ... ) : xxx; begin begintransaction; result := fimpl.dosth( ... ); endtransaction; end; function tstaticproxy.bar( ... ) : xxx; begin result := fimpl.bar( ... ); end;然后,在所有需要用到foo对象的地方,改用新的newfoo对象,如下:
var newfoo : ifoo; begin newfoo := tstaticproxy.create( foo ) as ifoo; ... // 之后就可以把newfoo完全当作foo一样使用了. end;可见,我们通过了一个proxy类代理了所有对ifoo接口的操作,相当于在从ifoo到tfooimpl之间插入了自己的代码,在某种程度上,这就是aop所谓的“横切”.... 下一页