【发布时间】:2011-08-23 05:16:10
【问题描述】:
我主要是一名 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,通过字节码修改,例如可以透明地将代码添加到(例如)第三方库,而无需修改源代码。
-
@Johan, ...这使得 AOP 编译器成为一个出色的黑客工具。
-
@weekens,确切地说,它不是 OOP 的替代品,而是一种应用 OOP 的便捷方式,有时是通过黑客攻击。
-
@Johan,这实际上是一个非常好的主意:听起来它可能比维护开源库的一部分直到修复提交要干净得多。 +1