I'm primarily a Java developer. I've met quite a few Java devs who love AOP. I've also been seeing more and more AOP "design patterns" emerging recently that seem to be fairly widely adopted. Even so, I'm still not convinced that AOP in OO code is a good idea in general, for a couple of reasons.
It adds "magic" to the code in the form of opaque complexity that can be extremely hard to debug, and can make it extremely hard to debug object oriented code that it affects.
It seems to me to be mostly unnecessary, and (worse) often used to avoid having to design well, or to compensate for previous poor design.
Here is an example that I've been seeing a lot of over the past couple of years, as a background for my question.
Before AOP (from the Hibernate docs)
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;
}
}
After AOP
@Transactional
public void saveMyEntityToTheDatabase(MyEntity entity) {
entityManager.persist(entity);
}
It seems like an obvious win for AOP to a lot of people. To me the original problem is symptomatic of inconsistent levels of API abstraction. That is, the EntityManager
is a lot lower level than the business-level API of the message using it. This problem can be solved with a more appropriate level of abstraction, and a better (OO) design.
An OO Solution
public void saveMyEntityToTheDatabase(MyEntity entity) {
database.performInTransaction(new Save(entity));
}
This solution assumes that the database
object contains the same kind of transactional logic that the aspect responsible that manages @Transactional
methods. This addresses my concerns above by making it more obvious that there is something managing the interaction with the EntityManager
, and not introducing another programming paradigm.
So finally, my question: what can AOP do that OOP can't? I'm slightly convinced of its usefulness in trace logging, and maybe default toString()
implementations or something similar, but I'd love to know if anyone's found it to be significantly better than OO for particular types of problems.