As you can see in the Wikipedia, an aspect is:
An aspect of a program is a feature linked to many other parts of the program, but which is not related to the program’s primary function. An aspect crosscuts the program’s core concerns, therefore violating its separation of concerns that tries to encapsulate unrelated functions. For example, logging code can crosscut many modules, yet the aspect of logging should be separate from the functional concerns of the module it cross-cuts. Isolating such aspects as logging and persistence from business logic is at the core of the aspect-oriented programming (AOP) paradigm.[1]
But, as always, things are much better understood with an example…
… your boss ask you to create a function that add two numbers. (This is for a very special client)
Then you program it and publish it in the company application server.
public static int addTwoNumbers(int a, int b) {
int sum = a + b;
return sum;
}
Wow, your first day!
… ask you to write a log line, because in that company “every function has a log” and “every one does it this way”.
Then you type:
public static int addTwoNumbers(int a, int b) {
// Print log
LOGGER.info("Funtion addTwoNumbers called, params {} and {}", a, b);
int sum = a + b;
return sum;
}
… ask you to check if the user is logged, because in that company “every function check it” and “every one does it this way”.
public static int addTwoNumbers(int a, int b) throws {
// Print log
LOGGER.info("Funtion addTwoNumbers called, params {} and {}", a, b);
// Check auth
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loggedInUser") == null) {
throw new UserNotAuthenticated();
}
int sum = a + b;
return sum;
}
… a few minutes later, the same guy returns and ask you to check the authorization level is enouh, because in that company “every function check it” and “every one does it this way”.
public static int addTwoNumbers(int a, int b) throws {\
// Print log
LOGGER.info("Funtion addTwoNumbers called, params {} and {}", a, b);
// Check auth
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loggedInUser") == null) {
throw new UserNotAuthenticated();
}
// Check authorization
int level = session.getAttribute("loggedUserAuthLevel")
if level < LEVEL_7) {
throw new UserAuthorizationNotEnough();
}
int sum = a + b;
return sum;
}
… ask you to save the results in a database, because in that company “every function save it” and “every one does it this way”.
public static int addTwoNumbers(int a, int b) throws {
// Print log
LOGGER.info("Funtion addTwoNumbers called, params {} and {}", a, b);
// Check auth
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loggedInUser") == null) {
throw new UserNotAuthenticated();
}
// Check authorization
int level = session.getAttribute("loggedUserAuthLevel")
if level < LEVEL_7) {
throw new UserAuthorizationNotEnough();
}
int sum = a + b;
// Save on db
String sql = "Insert into addTwoNumebrTable(a,b,result) values(?,?,?)";
pst = conn.prepareStatement(sql);
pst.setInt(1, a);
pst.setInt(2, b);
pst.setInt(3, sum);
pst.execute();
return sum;
}
… ask you to send the function information to exploit the data. You answer that the information can found in hte log and also in the explotation database, but he answer: “we are marketing, we need Google Analytics”.
… and the you add it.
public static int addTwoNumbers(int a, int b) throws {
// Print log
LOGGER.info("Funtion addTwoNumbers called, params {} and {}", a, b);
// Check auth
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loggedInUser") == null) {
throw new UserNotAuthenticated();
}
// Check authorization
int level = session.getAttribute("loggedUserAuthLevel")
if level < LEVEL_7) {
throw new UserAuthorizationNotEnough();
}
int sum = a + b;
// Save on db
String sql = "Insert into addTwoNumebrTable(a,b,result) values(?,?,?)";
pst = conn.prepareStatement(sql);
pst.setInt(1, a);
pst.setInt(2, b);
pst.setInt(3, sum);
pst.execute();
// Google Analytics
Bundle parameters = new Bundle();
params.putString("function", "addTwoNumbers");
params.putInt("a", a);
params.putInt("b", b);
params.putInt("sum", sum);
analytics.setDefaultEventParameters(parameters);
return sum;
}
This shit was a function to add two numbers!!!
Someone may think that this project requires an OOP framework that can solve auhtentication, authorization, persistence, logging, in a more designable way. But this approach tend to lack of the flexibility needed to add new kinds of functionality once the desing is settled.
There is other way to solve this: Aspect-oriented programming
The definition in the wikipedia is perfectly correct. Any kind of code that affects the project in a transversal way, can be considered an aspect. Not everything is an aspect, there are some aspects of programming that are evident. Among them we find:
In a simple way to say it: aspect-oriented programming is a way to add some functionality to an existing function, without editing or modifying it.
There are some techniques to accomplish this. One of them is the interceptor pattern, other is the Decorator pattern and almost every programming language has its own aspect implementation.
To understand this type of programming, first you must change your mind in the way you solve algorithms. Specially if you are used to do OOP and apply Design Patterns, because this king of programming requires to know every aspect you are going to use before implementing the project.
In Aspect-oriented programming, instead defining an structure of classes that interact to solve transversal functionality, you can design the bussines model and logic, and then add the different aspects to that functionality. Wikipedia sample code is really good to see this way to solve use cases.
I like this way to program for this reason:
What negative point are?