--- /dev/null
+package caching;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public aspect Caching {
+ private Map<Integer,Integer> cache = new HashMap<Integer,Integer>();
+
+ Integer around(Integer a): execution(* Fib.calc*(*)) && args(a) {
+ if(cache.containsKey(a)){
+ System.out.println("Using cached value for: " + a);
+ return cache.get(a);
+ }
+ else {
+ Integer result = proceed(a);
+ cache.put(a, result);
+ return result;
+ }
+ }
+}
--- /dev/null
+package caching;
+
+public class Fib {
+ public static int calc(int n){
+ if (n < 2) return 1;
+ return calc(n-1) + calc(n-2);
+ }
+ public static Integer calc2(Integer n){
+ if (n < 2) return 1;
+ return calc2(n-1) + calc2(n-2);
+ }
+}
--- /dev/null
+//package caching;
+//
+//public aspect FibCaching extends Caching<Integer,Integer> {
+//
+// pointcut cached() : execution(Integer Fib.calc(Integer));
+//
+//}
+
--- /dev/null
+package caching;
+
+public class Test {
+
+ public static void main(String[] args) {
+ System.out.println(Fib.calc(30));
+ System.out.println(Fib.calc2(30));
+ }
+}
--- /dev/null
+package caching;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract aspect Caching<K,V> {
+ private Map<K,V> cache = new HashMap<K,V>();
+
+ abstract pointcut cached();
+
+ V around(K a): cached() && args(a) {
+ if(cache.containsKey(a)){
+ System.out.println("Using cached value for: " + a);
+ return cache.get(a);
+ }
+ else {
+ V result = proceed(a);
+ cache.put(a, result);
+ return result;
+ }
+ }
+}
--- /dev/null
+package caching;
+
+public class Fib {
+ public static int calc(int n){
+ if (n < 2) return 1;
+ return calc(n-1) + calc(n-2);
+ }
+}
--- /dev/null
+package caching;
+
+public aspect FibCaching extends Caching<Integer,Integer> {
+
+ pointcut cached() : execution(int Fib.calc(int));
+
+}
+
--- /dev/null
+package caching;
+
+public class Test {
+
+ public static void main(String[] args) {
+ System.out.println(Fib.calc(30));
+ }
+}