OOP is mainly used to organise your business logic while AOP helps to organise your non-functional things like Auditing, Logging, Transaction Management , Performance Tracking, Security etc
This way you can decouple your business logic with non-fictional logic that makes code cleaner.
OOP and AOP are not mutually exclusive. AOP can be good addition to OOP.
AOP provides a nice way to implement cross-cutting concerns like logging, performance tracking, security over different classes in your application without having to change the classes themselves.
These cross-cutting concerns are pieces of logic that have to be applied at many places but actually don't have anything to do with the business logic.
You shouldn't see AOP as a replacement of OOP, more as an nice add-on, that makes your code more clean, loosely-coupled and focused on the business logic. So by applying AOP you will get 2 major benefits:
1. The logic for each concern is now in one place, as opposed to being scattered all over the code base.
2. classes are cleaner since they only contain code for their primary concern (or core functionality) and secondary concerns have been moved to aspects.
This is a way of doing runtime-weaving.
Example;-
1. Assume you have a graphical class with many "set()" methods.
2. After each set() method, the data of the graphics changed, thus the graphics changed and thus the graphics need to be updated on screen.
3. Assume to repaint the graphics you must call "Display.update()".
The classical approach is to solve this by adding more code. At the end of each set method you write
void set(...) {
:
:
Display.update();
}
If you have 3 set-methods, that is not a problem. If you have 200 (hypothetical), it's getting real painful to add this everywhere.
Also whenever you add a new set-method, you must be sure to not forget adding this to the end, otherwise you just created a bug.
AOP solves this without adding tons of code, instead you add an aspect:
after() : set() {
Display.update();
}
And that's it! Instead of writing the update code yourself, you just tell the system that after a set() pointcut has been reached, it must run this code and it will run this code.
No need to update 200 methods, no need to make sure you don't forget to add this code on a new set-method. Additionally you just need a pointcut:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
What does that mean? That means if a method is named "set*" (* means any name might follow after set), regardless of what the method returns (first asterisk) or what parameters it takes (third asterisk) and it is a method of MyGraphicsClass and this class is part of the package "com.company.*", then this is a set() pointcut. And our first code says "after running any method that is a set pointcut, run the following code".
See how AOP elegantly solves the problem here? Actually everything described here can be done at compile time. A AOP preprocessor can just modify your source (e.g. adding Display.update() to the end of every set-pointcut method) before even compiling the class itself.
This way you can decouple your business logic with non-fictional logic that makes code cleaner.
OOP and AOP are not mutually exclusive. AOP can be good addition to OOP.
AOP provides a nice way to implement cross-cutting concerns like logging, performance tracking, security over different classes in your application without having to change the classes themselves.
These cross-cutting concerns are pieces of logic that have to be applied at many places but actually don't have anything to do with the business logic.
You shouldn't see AOP as a replacement of OOP, more as an nice add-on, that makes your code more clean, loosely-coupled and focused on the business logic. So by applying AOP you will get 2 major benefits:
1. The logic for each concern is now in one place, as opposed to being scattered all over the code base.
2. classes are cleaner since they only contain code for their primary concern (or core functionality) and secondary concerns have been moved to aspects.
This is a way of doing runtime-weaving.
Example;-
1. Assume you have a graphical class with many "set()" methods.
2. After each set() method, the data of the graphics changed, thus the graphics changed and thus the graphics need to be updated on screen.
3. Assume to repaint the graphics you must call "Display.update()".
The classical approach is to solve this by adding more code. At the end of each set method you write
void set(...) {
:
:
Display.update();
}
If you have 3 set-methods, that is not a problem. If you have 200 (hypothetical), it's getting real painful to add this everywhere.
Also whenever you add a new set-method, you must be sure to not forget adding this to the end, otherwise you just created a bug.
AOP solves this without adding tons of code, instead you add an aspect:
after() : set() {
Display.update();
}
And that's it! Instead of writing the update code yourself, you just tell the system that after a set() pointcut has been reached, it must run this code and it will run this code.
No need to update 200 methods, no need to make sure you don't forget to add this code on a new set-method. Additionally you just need a pointcut:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
What does that mean? That means if a method is named "set*" (* means any name might follow after set), regardless of what the method returns (first asterisk) or what parameters it takes (third asterisk) and it is a method of MyGraphicsClass and this class is part of the package "com.company.*", then this is a set() pointcut. And our first code says "after running any method that is a set pointcut, run the following code".
See how AOP elegantly solves the problem here? Actually everything described here can be done at compile time. A AOP preprocessor can just modify your source (e.g. adding Display.update() to the end of every set-pointcut method) before even compiling the class itself.
No comments:
Post a Comment