/* AspectJ sample program. At the risk of over-generalizing AOP, I will list a number of basic principles that AOP is built around: * CROSSCUTTING. * JOIN POINT * SEPERATION OF CONCERNS * WEAVING The idea of these principals is to make programming more modular, like all programming languages and programs should do. More specifically, they make program components more *loosely coupled* To understand these principles, you really need to look at some programs, then write some yourself. The company MATHGEEKSOFT has become a major provider of software for math geeks and have hired you to join their programming team. */ ////// base program, or BASE aspect: class base { public int fact(int n, int ax) { if (n<2) return ax; else return fact(n-1,ax*n); } public int fib(int n) { if (n<3) return 1; else return fib(n-1) + fib(n-2); } public boolean divisible(int a, int b) { return (a%b == 0); } } //base public class mathfuns { public static void main(String[] args) { base B = new base(); System.out.println("the factorial of 6 is "+B.fact(6,3)); System.out.println("is 5 divisible by zero? "+B.divisible(5,0)); System.out.println("the 100th fibonacci number is "+B.fib(100)); System.out.println("the -4th fibonacci number is "+B.fib(-4)); } //main } /* The base program above consists of three procedures, each relatively simple and elegant. However, several ASPECTS are missing from the program: ASPECT1: INVARIANCE There is no parameter check. That is, there is no check that the n parameter of the fib and fact functions are negative. Similarly, there is no check that the b parameter of divisible is zero. There is also no guarantee that the initial value for ax passed to the tail recursive fact function is 1. ASPECT2: OPTIMIZATION fib(100) will take about 20000 years to run. factorial will overflow stack because java doesn't optimize tail recursion. ASPECT3: IO How do we get user input for the functions and output the results? ASPECT4: PROFILING We may want to record when and how many times each function is called. ASPECT5: SECURITY We don't want nasty people to call our functions. We want to protect the functions with a password. You can easily think of other aspects.... First, let's consider how you would solve these problems with conventional oop techniques. You want to do this in a modular way (don't write spaghetti code). Assume further that each aspect is the responsibility of a separate programming team, who will work independently and only meet at the end to determine how to "weave" the various components together. */ ////// INVARIANCE TEAM code: class invariancechecking extends base { public int fact(int n) { if (n<0) throw new Error("bad parameter"); else return super.fact(n,1); // make sure ax is initially one } public int fib(int n) { if (n<0) throw new Error("bad parameter"); return super.fib(n); } public boolean divisible(int a, int b) { return (b!=0) && super.divisible(a,b); } } ////// PROFILING TEAM code class profilingclass extends base { private int fibcount = 0; private int factcount = 0; private int divcount = 0; public int fib(int n) { fibcount++; return super.fib(n); } public int fact(int n, int ax) { factcount++; return super.fact(n,ax); } public boolean divisible(int a, int b) { divcount++; return super.divisible(a,b); } public void profile() { System.out.println("fib was called "+fibcount+" times"); System.out.println("fact was called "+factcount+" times"); System.out.println("divisible was called "+divcount+" times"); } } /*** Each programming team is very proud of their work and believe that they have provided the best possible solution to the task they were assigned. But now we have a meeting with the three teams where all three code fragments, each addressing a separate aspect of the program, needs to be merged together. How would you combine the code for INVARIANCE and OPTIMIZATION, for example. Also, there should be the option of leaving out the PROFILING code. That is, there should be the flexibility of profiling our code or not, since there's an overhead involved. To make matters worse, the company was quick to make a buck and have already shipped out copies of the BASE class. That is, there are already a lot of programs that make calls to the base program methods. How are you going to make sure that these existing programs can benefit from your refinements? With OOP technology, all three teams have to go back to the drawing board and start over, because there is no choice but to tightly couple each combination. That is, to combine two aspects, we need yet another class with a new set of procedures. All previous software that made use of BASE will have to be carefully modified as well. This is still possible, but what if next week the SECURITY and IO teams finally finish their work and want to meet with you? Are you going to go through this again? What if next week the boss wants to add a function to the three that already exists? ***/