AOP 可以做哪些 OOP 无法执行的操作?

2022-09-01 10:51:21

我主要是一名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;
    }
}

在 AOP 之后

@Transactional
public void saveMyEntityToTheDatabase(MyEntity entity) {
    entityManager.persist(entity);
}

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

OO 解决方案

public void saveMyEntityToTheDatabase(MyEntity entity) {
    database.performInTransaction(new Save(entity));
}

此解决方案假定对象包含与负责管理方法的方面相同的事务逻辑。这解决了我上面的顾虑,因为它更清楚地表明,有一些东西可以管理与 的交互,而不是引入另一种编程范式。database@TransactionalEntityManager

最后,我的问题是:AOP能做什么,而OOP做不到的?我稍微相信它在跟踪日志记录中的有用性,也许是默认实现或类似的东西,但我很想知道是否有人发现它在特定类型的问题方面明显优于OO。toString()


答案 1

AOP 是 OO;方面对象。

我不明白为什么非此即彼的心态。

AOP 是链式、跨领域问题(例如日志记录、安全性、事务、远程代理等)的完美选择。

更新:

我认为OP提出的批评是主观的,并不像所说的那样普遍普遍。没有证据的陈述可以在没有证据的情况下驳回。

我不相信使用魔法,但如果你理解它,AOP就不是魔法。我明白了。也许OP没有。如果是这样的话,并且OP对OO解决方案更满意,我会说去吧。

“在我看来是不必要的”仅仅是一个观点,没有证据。除了“我不同意”之外,没有答案。

我认为AOP非常适合这些情况,因为我可以以声明性的方式应用它。我可以编写一个方面类一次,然后通过细粒度控制将其应用于许多地方,在配置而不是代码中更改它。我可以挑选哪些方法,类和包在配置中应用了一个方面。

尝试使用手写的OO方法。

此外,AOP面向对象的。你可以把它看作是一个聪明的人,给你一个特定于领域的语言或框架,用于你想手工做的事情。共同的特征已经抽象出来,变成了更一般的东西。为什么会有人反对呢?


答案 2

简短的答案是...无。不过,AOP增加了一点,我在美国海军陆战队的日子里称之为FM,当为平民观众清理时,这意味着“疯狂的魔术”。你是对的,在你引用的第一种情况下,绝对没有任何东西是在第二种情况下没有实现的。我认为这场运动背后的主要原因是一个清晰度的问题,以及代码中“更少仪式”的口号。因此,您可以编写代码来处理事务,或者省去AOP的仪式,AOP由供应商提供,或者容器可能比您手动编写的代码更好地进行测试。AOP的另一个优点是,它可以在部署描述符,Spring配置文件等中更改,然后可以在不更改实际代码的情况下更改需求。因此,您手写的昂贵代码继续表达您的意思是付费的业务逻辑,并且“FM”层处理诸如事务,日志记录等之类的事情,并大量洒上AOP pixie灰尘。

当然是YMMV。