What is | AOP? |
AOP has been first introduced by Gregor Kickzales in 1996. Like structured programming and Object-Oriented programming introduced a new approach for designing programs and a set of guidelines to make more readable and reusable code, AOP is a philosophy that is related to style of programming. It addresses issues that can be solved in other approaches, but in a more elegant way. To understand the spirit of AOP, you must understand the following issues:
JAC furnishes a set of programming concepts that allows the user to implement the dependency inversion in a clean way.
Here is a core business class that performs simple calculi:
public class Calcul { int value=0; public void add(int toadd) { value+=toadd; } public void sub(int tosub) { value-=tosub; } }
Let us imagine that, in the application, we do not want the value
field to be negative. This is a constraint that will also be
applicable to all the other classes of the application since, in
this business, we don't want to see negative values.
Thus, the test that will be added to check that the value is never negative will crosscut all the business classes and pollute the code that will be harder to read an maintain. Moreover, in an application where the constraint is different or where there is no constraints at all, my business classes will be harder to re-use as is.
JAC and its AOP features allows you to externalize all the tests within a well modularized code called an aspect component. The effect of this code is to actually reverse the dependency between the code that performs the business calculi and the code that tests the constraints. Here is the aspect code:
01> public class TestAC extends AspectComponent { 02> public TestAC() { 03> pointcut( "Calcul", "sub", LimiterWrapper.class, "limit" ); 04> } 05> public class LimiterWrapper extends Wrapper { 06> public void limit(Interaction i) { 07> if(((Integer)getFieldValue(i.wrappee,"value")).intValue() 08> - ((Integer)args[0]).intValue() < 0 ) 09> throw new Exception("<0 forbidden"); 10> proceed(); 11> } 12> ... 13>} }
Of course it is more complex than adding a simple line of test but in the long term and for real complex applications the benefits are huge.
Aspect code explaination:
sub
method of the calcul
class, but it could denote a
much more complex set of objects or methods --- hence a
possibility to generalize the process to all the business
classes)limit
i.args[0]
is the parameter of the method
that is associated to the interaction and that
i.wrappee
is the calcul object. So we can test
them and throw an exception if the value
field is
negative.sub
method. proceed
is a special method of wrappers
that allows the programmer to ask for the realization of the
current joinpoint (continue the interaction).JAC provides 2 levels to play with aspects:
TestAC
aspect so that it provides a
configuration method instead of a hardcoded pointcut:
public class TestAC extends AspectComponent { final int bound = 0; public addTest(String classes, String methods, int bound) { pointcut( classes, method, LimiterWrapper.class, "limit" ); this.bound = bound; } public class LimiterWrapper extends Wrapper { public void limit(Interaction i) { if(((Integer)getFieldValue(i.wrappe,"value")).intValue() - ((Integer)i.args[0]).intValue() < bound ) throw new Exception("<"+bound+" forbidden"); return proceed(i); } ... } }Then you can use the aspect just by writing a configuration file such as (this is easy so I do not explain it):
addTest "Calcul" "sub" 0;
Finally, JAC furnishes a set of aspects and an environment for distribution (deployment, remote communication, sessions, authentication, web interface). All the aspect features also work when the application is distributed so that you can write aspects that have global and distributed influence on the application. A set of aspects that implement distribution-related concerns such as consistency, broadcasting or load-balancing are provided by JAC. We hope that you'll enjoy them and find them useful!