AOP能做什么OOP不能做?

Dan*_*iel 31 java oop aop

我主要是一名Java开发人员.我遇到了很多喜欢AOP的Java开发者.我也看到越来越多的AOP"设计模式"最近出现,似乎被广泛采用.即便如此,由于几个原因,我仍然不相信OO代码中的AOP通常是个好主意.

  1. 它以不透明的复杂性形式为代码添加了"魔力",这可能非常难以调试,并且可能使调试它所影响的面向对象的代码变得非常困难.

  2. 在我看来,大多数情况下是不必要的,而且(更糟糕的是)经常习惯于避免设计好,或者补偿以前糟糕的设计.

这是我在过去几年中经常看到的一个例子,作为我的问题的背景.

在AOP之前(来自Hibernate文档)

public void saveMyEntityToTheDatabase(MyEntity entity) {
    EntityTransaction tx = null;
    try {
        tx = entityManager.getTransaction();
        tx.begin();
        entityManager.persist(entity);
        tx.commit();
    } catch (RuntimeException e) {
        if(tx != null && tx.isActive()) {
            tx.rollback();
        }
        throw e;
    }
}
Run Code Online (Sandbox Code Playgroud)

AOP之后

@Transactional
public void saveMyEntityToTheDatabase(MyEntity entity) {
    entityManager.persist(entity);
}
Run Code Online (Sandbox Code Playgroud)

对许多人而言,AOP似乎是一个明显的胜利.对我来说,原始问题是API抽象级别不一致的症状.也就是说,它EntityManager比使用它的消息的业务级API低很多.这个问题可以通过更合适的抽象级别和更好的(OO)设计来解决.

OO解决方案

public void saveMyEntityToTheDatabase(MyEntity entity) {
    database.performInTransaction(new Save(entity));
}
Run Code Online (Sandbox Code Playgroud)

此解决方案假定database对象包含与负责管理@Transactional方法的方面相同类型的事务逻辑.这解决了我上面关注的问题,因为它更明显地表明存在管理与之交互的东西EntityManager,而不是引入另一种编程范例.

最后,我的问题是:AOP可以做什么OOP不能?我有点确信它在跟踪日志记录中的用处,也许是默认toString()实现或类似的东西,但我很想知道是否有人发现它比OO明显优于特定类型的问题.

duf*_*ymo 12

AOP是OO; 方面对象.

我不明白为什么这两个/或心态.

AOP是链接,跨领域关注点(例如日志记录,安全性,事务,远程代理等)的完美选择.

更新:

我认为OP提出的批评是主观的,并不像所述普遍普及.没有证据的断言可以在没有证据的情况下被驳回.

我不相信使用魔法,但如果你了解它,AOP并不神奇.我明白了.也许OP没有.如果是这种情况,并且OP对OO解决方案更加满意,我会说它去吧.

"似乎对我来说是不必要的"仅仅是一种意见,没有证据.除了"我不同意"之外,没有答案.

我认为AOP对于那些案例是完美的,因为我可以以声明的方式应用它.我可以编写一个方面类,并在许多地方应用它进行细粒度控制,在配置而不是代码中更改它.我可以选择哪些方法,类和包在配置中应用了一个方面.

尝试使用手写的OO方法.

此外,AOP 面向对象的.您可以将其视为一个聪明的人,为您提供您想要手动完成的特定领域语言或框架.共同特征被抽象为更一般的东西.为什么有人会反对呢?

  • "AOP是OO"和"Aspects is objects"是完全错误和无聊的.AOP的分离特性是通过添加运行代码(建议)的外部钩子(切入点)来无形地改变代码的行为.这些都没有任何内容使用OOP.AOP和OOP是兼容但完全不同的概念 - 这个答案是完全错误的. (3认同)

mez*_*zmo 10

简短的回答是......没有.AOP虽然增加了我在美国海军陆战队作为FM的日子里所提到的一些内容,当为平民观众清理时意味着"怪异的魔法".你是对的,在你引用的第一种情况下,第二种情况并没有实现.我认为这一运动背后的主要原因是一个清晰的问题,以及代码中"少礼"的颂歌.因此,您可以编写代码来处理交易,或者免除由供应商提供的AOP的仪式,或者容器可能比您手动编写的代码更好地测试.AOP有利的另一点是它可以在部署描述符,Spring配置文件等中进行更改,然后如果您的需求发生更改而不更改实际代码,则可以更改它.因此,您手写昂贵的代码将继续表达您需要支付的业务逻辑,并且"FM"层处理交易,日志记录等事务,并自由地使用AOP小精灵粉尘.

YMMV当然.


Ade*_*ari 8

对我而言,AOP是拦截器模式的简写.拦截器模式本身是从模板方法,AFAICS 派生(或影响或得到了想法).

一个流行的例子InterceptorServlet Filter.我们知道在许多情况下这些非常有用.

由于所有这些模式都是有用的,因此从这些模式衍生的AOP也是有用的.而你自己说的很少用法.


Ita*_*man 6

一般来说,所有形式的问题"什么不能做?" 毫无意义.所有通用语言同样强大(参见:Church's Thesis).

语言的区别,因此,在没有什么可以做,而在于怎么他们这样做.换句话说,你需要做多少工作才能在一种语言中获得一些行为,而在另一种语言中获得相同行为的工作量.