我主要是一名 Java 开发人员。我遇到了很多喜欢 AOP 的 Java 开发人员。我还看到最近出现的越来越多的 AOP“设计模式”似乎被广泛采用。尽管如此,出于几个原因,我仍然不相信 OO 代码中的 AOP 是一个好主意。
它为代码中的代码添加了“魔力” 不透明的复杂性形式,可以 非常难以调试,并且可以 使调试变得非常困难 它的面向对象代码 影响。
在我看来主要是 不必要的,并且(更糟)经常使用 避免必须精心设计,或 弥补以前的贫穷 设计。
这是我在过去几年中经常看到的一个示例,作为我的问题的背景。
在 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 抽象级别不一致的症状。也就是说,EntityManager
比使用它的消息的业务级 API 低很多。这个问题可以通过更合适的抽象级别和更好的(OO)设计来解决。
OO 解决方案
public void saveMyEntityToTheDatabase(MyEntity entity) {
database.performInTransaction(new Save(entity));
}
此解决方案假定 database
对象包含与负责管理 @Transactional
方法的切面相同类型的事务逻辑。这解决了我上面的顾虑,更明显的是管理与 EntityManager
的交互,而不是引入另一个编程范式。
最后,我的问题是:AOP 能做什么而 OOP 不能?我稍微相信它在跟踪日志记录中的用处,也许默认 toString()
实现或类似的东西,但我很想知道是否有人发现它是在特定类型的问题上明显优于 OO。
最佳答案
AOP 是面向对象的;方面是对象。
我不明白为什么是非此即彼的心态。
AOP 是链式横切关注点(例如日志记录、安全性、事务、远程代理等)的完美选择
更新:
我认为 OP 提出的批评是主观的,并不像所说的那样普遍。没有证据的断言可以在没有证据的情况下被驳回。
我不相信使用魔法,但如果你了解 AOP,它就不是魔法。我明白了。也许OP没有。如果是这种情况,并且 OP 对 OO 解决方案更满意,我会说去吧。
“在我看来是不必要的”只是一种意见,没有证据。除了“我不同意”之外,没有其他答案。
我认为 AOP 非常适合这些情况,因为我可以以 声明性 的方式应用它。我可以一次编写一个方面类,并通过细粒度控制将其应用到许多地方,在配置而不是代码中更改它。我可以选择哪些方法、类和包在配置中应用了一个方面。
尝试使用手写的 OO 方法。
此外,AOP 是面向对象的。您可以将其视为一个聪明的人,为您提供特定领域的语言或框架来完成您想要手动完成的工作。共同特征已被抽象为更一般的东西。为什么会有人反对?
关于java - AOP 能做什么而 OOP 不能做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5963169/