论坛首页 Java企业应用论坛

殊途同归

浏览 17252 次
锁定老帖子 主题:殊途同归
该帖已经被评为精华帖
作者 正文
   发表时间:2004-08-14  
不错,如果比较直接使用dynamic proxy的代码和使用aspectJ的代码,确实有一个区别是:
要用aspectJ截获某一个interface,直接在aspectJ里动手脚。而用dynamic proxy的话,就要至少在代码的某个地方明确的说:我想截获这个interface。

呵呵。不过,还真不好说哪个更好。

我个人是更喜欢凡事explicit一点,只有明确要求的,我才给你。

而且,无论如何,我想这个在若干个地方(其实,还是有可能通过OO的设计把cache的调用集中在一个地方的)调用cache(...)函数并不能算是什么大负担吧?如果使用了aspectJ只能给我这么点好处,我还是拥抱简单的好。

另外,如果使用pico等容器来组装对象的话,我相信一定有一个方法可以在容器级别指定:我要对这些这些类使用cache。(至少我相信自己可以做出这么个库出来)

这样,连这点区别也不存在了。



对第二点,这其实就是aop这个词的定义问题。dynamic proxy/interceptor属于oo还是属于aop?
我对这点其实并不太在乎。在我看来,dynamic proxy虽然有用,但是它只是作为对传统基于静态强类型的接口编程的补充。(在动态类型的语言里,如python,甚至不需要dynamic proxy)。而如果语言支持某种如c++模板式的生成式编程,也许可以不需要dynamic proxy。 不过无论如何,它本身还不配称为一个XOP。你不能围绕dynamic proxy来构建你的整个系统。

不过,就让我们假设aop就是一个静态类型安全的,语法更简洁的interceptor吧。那么就如此了吗?这就是aop了吗?



另外,我在另一个帖子里提到的一个问题,我觉得这是很能区分传统的面向接口和aop的:
就是aspectJ支持within()这个直接侵入黑箱代码的东西。这用dynamic proxy是无论如何模拟不出来的。
dynamic proxy归根结底还是一个OO的proxy pattern,它只能在输入输出,也就是黑箱的边界起作用,不可能深入模块黑箱的内部。
那么aop哥们们对这个问题怎么看呢?
0 请登录后投票
   发表时间:2004-08-14  
ajoo 写道

不错,如果比较直接使用dynamic proxy的代码和使用aspectJ的代码,确实有一个区别是:
要用aspectJ截获某一个interface,直接在aspectJ里动手脚。而用dynamic proxy的话,就要至少在代码的某个地方明确的说:我想截获这个interface。

呵呵。不过,还真不好说哪个更好。

我个人是更喜欢凡事explicit一点,只有明确要求的,我才给你。

而且,无论如何,我想这个在若干个地方(其实,还是有可能通过OO的设计把cache的调用集中在一个地方的)调用cache(...)函数并不能算是什么大负担吧?如果使用了aspectJ只能给我这么点好处,我还是拥抱简单的好。

另外,如果使用pico等容器来组装对象的话,我相信一定有一个方法可以在容器级别指定:我要对这些这些类使用cache。(至少我相信自己可以做出这么个库出来)
这样,连这点区别也不存在了。


对啊。EJB容器,组件容器,就是这样的东西。
但前提是,容器本身提供了这样的interceptor. 比如,cache, transaction, secruity.
只是AOP的思路走的更远一点。即使容器,或者类的基类,基本接口没有提供这样的interceptor,AOP也能够把interceptor插入到任何pointcut。AOP不需要系统实现预留接口。

对于这个例子本身,我也觉得,你的显示decorator方式不错,
new Cache(new Transaction(new Secruity( .... interface, object)))
能够很清楚地表示Aspect的顺序。

我还需要再多思考一下,找到AOP更适合应用的场合和例子。
(这是因为我个人的眼界所限,并不是AOP的限制 :-))

引用

对第二点,这其实就是aop这个词的定义问题。dynamic proxy/interceptor属于oo还是属于aop?
我对这点其实并不太在乎。在我看来,dynamic proxy虽然有用,但是它只是作为对传统基于静态强类型的接口编程的补充。(在动态类型的语言里,如python,甚至不需要dynamic proxy)。而如果语言支持某种如c++模板式的生成式编程,也许可以不需要dynamic proxy。 不过无论如何,它本身还不配称为一个XOP。你不能围绕dynamic proxy来构建你的整个系统。

不过,就让我们假设aop就是一个静态类型安全的,语法更简洁的interceptor吧。那么就如此了吗?这就是aop了吗?

另外,我在另一个帖子里提到的一个问题,我觉得这是很能区分传统的面向接口和aop的:
就是aspectJ支持within()这个直接侵入黑箱代码的东西。这用dynamic proxy是无论如何模拟不出来的。
dynamic proxy归根结底还是一个OO的proxy pattern,它只能在输入输出,也就是黑箱的边界起作用,不可能深入模块黑箱的内部。
那么aop哥们们对这个问题怎么看呢?


AOP不是为了代替OOP. AOP的目的是在OOP力所未及的领域,发挥作用。
前面我提到了一点函数式编程。函数式编程本身不能用来开发系统,但对于某些领域非常合适。我觉得,AOP有点类似的意思。ponitcut类似于pattern match. Aspect类似于入口点。
我欣赏AOP的思路,但我只是一个AOP的新手,也许连入门都算不上,现在还没有能力完全阐述AOP的精髓。

AspectJ操作的是源代码。假设我们有这样的代码。
f1();{
  a = 0;
}

main();{
  f1();
}


如果pointcut定义是call f1(). 那么生成的代码是
f1();{
  a = 0;
}

main();{
  before_advice();;
  f1();
  after_advice();;
}


如果pointcut定义是within f1(). 那么生成的代码是
f1();{
  before_advice();;
  a = 0;
  after_advice();;
}

main();{
  f1();
}


以上只是一个示例,具体情况如何,还需要实际监测。
最直接的办法:不同的poincut定义,编译出来的class文件。反编译这些class文件。

within和call的区别就在于,call是在参数入栈之前截获,within是在参数入栈之后截获。
within的功能主要在于更好地定义pointcut的作用范围,过滤掉一些范围。
比如,call f1() && within main() 表示只有在main()代码范围内, 对f1()的调用才会被截获。

对于within, 我也只有这么一点看法。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics