… AspectJ Orientated Programming Continued
Last month I wrote briefly about a computer science seminar course that I am taking, Programing Skills: Aspect Orientated Programming.
The best way to show the differences between AOP and the “classic” OOP (object orientated programming) paradigm is the Observerable design pattern.
For example: Take a LinkedList that you wish to monitor.
- Whenever the list is changed, print “List is changed”
- Whenever the list is changed, print if the list is empty
To do this with the classic OOP Observable pattern, you have to create two Observer classes (extending some sort of super Observer class ), make your LinkedList implement the Observerable class, and make a test class to attach said Observers to your LinkedList.
To do the same in AOP, you simply make an Aspect - that watches when your class has been accessed, and acts accordingly based on advice that you give it.
Code below, read entire post for snippets.
import edu.rit.cs.helio.util.LinkedList;
/**
* @author Nicholas Pike (nsp1828)
*
* AbstractObserver contains only a single pointcut, which is shared
* for other observers observing the home-brew LinkedList class
*
*/
public abstract aspect AbstractObserver {
pointcut change(LinkedList list):
target (list) &&
!within(LinkedList) &&
(call(void LinkedList.append(*)) ||
call(void LinkedList.rotate(*)) ||
call(void LinkedList.sort()) ||
call(void LinkedList.prepend(*)) ||
call(void LinkedList.discard_first()) ||
call(void LinkedList.discard_last()));
}
import edu.rit.cs.helio.util.LinkedList;
/**
* @author Nicholas Pike (nsp1828)
*
* Extends AbstractObserver, which contains our pointcut that is used
* to observe the home-brew LinkedList class
*
*/
public aspect EmptyObserver extends AbstractObserver {
after(LinkedList list) returning: change(list) {
if (list.is_empty()) {
System.out.println("\tList is empty.");
} else {
System.out.println("\tList is not empty.");
}
}
}
import edu.rit.cs.helio.util.*;
/**
* @author Nicholas Pike (nsp1828)
*
* Extends AbstractObserver, which contains our pointcut that is used
* to observe the home-brew LinkedList class
*
*/
public aspect ListObserver extends AbstractObserver {
after(LinkedList list) returning: change(list) {
System.out.println("\tChanged:"+list.toString());
}
}
Then using the “ajc” compiler (a special java compiler), the byte code of your resulting classes are modified to support aspects, which can then be run by any java runtime. There’s no need to explicitly attach the “Observer Aspects” to your classes for them to observe them. Just compile then alongside everything else!
I have no idea what just happened but I liked it.
I think what I’m trying to say is… You just popped my AOP cherry.
Randy Aldrich
7 Jan 08 at 8:31 pm