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.
OOP is mainly used to organise your business logic while AOP helps to organise your non-functional things like Auditing, Logging, Transaction Management, Security etc. This way you can decouple your business logic from non-functional logic, which makes code cleaner.
You can use AOP to reduce code clutter by improving the readability and maintainability of your code. It should be noted that AOP is just a new programming paradigm -- it doesn't replace OOP in any way. Rather, it complements OOP by providing you another way to achieve modularity and also reduce code clutter.
OOP provides you with high quality of the Software faster development of software and lower cost of development allows more time and resources to be used in the verification of the software.
These include: design patterns, abstraction, encapsulation, modularity, polymorphism, and inheritance. When not to use OOP: Putting square pegs in round holes: Don't wrap everything in classes when they don't need to be. Sometimes there is no need and the extra overhead just makes your code slower and more complex.
AOP is OO; Aspects are objects.
I don't understand why the either/or mentality.
AOP is the perfect choice for chained, cross-cutting concerns (e.g. logging, security, transactions, remote proxying, etc.)
UPDATE:
I think the criticisms offered by the OP are subjective and not as universally widespread as stated. Assertions stated without proof can be dismissed without proof.
I don't believe in using magic, but AOP is not magic if you understand it. I understand it. Perhaps the OP does not. If that's the case, and the OP is more comfortable with an OO solution, I'd say go for it.
"Seems to me to be unnecessary" is a mere opinion, offered without proof. There's no answer to that except "I disagree."
I think AOP is perfect for those cases because I can apply it in a declarative way. I can write an aspect class once and apply it in many places with fine-grained control, changing it in configuration rather than code. I can pick and choose which methods, classes, and packages have an aspect applied to them in configuration.
Try that with a hand-written OO approach.
Besides, AOP is object-oriented. You can look at it as a smart person giving you a domain-specific language or framework for what you want to do by hand. The common features have been abstracted out into something more general. Why would anyone object to that?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With