Download presentation
Presentation is loading. Please wait.
1
Aspect-Oriented Programming Gregor Kiczales University of British Columbia © Copyright 2004, Gregor Kiczales. All rights reserved.
2
CASCON 2004 2 Contents What is AOP How AOP works What AOP does for code and designs What’s happening with AOP today
3
CASCON 2004 3 Consider developing… a simple drawing application (JHotDraw)
4
CASCON 2004 4 Intuitively thinking of objects? Points, Lines… Drawing surfaces GUI Widgets … Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) *
5
CASCON 2004 5 most programmers would have used this has poor design and code modularity! 2212 6593 4329 8665 24 collection of procedures to operate on and manage table entries 6758 + In 1969…
6
CASCON 2004 6 What is OOP? a learned intuitive way of thinking design concepts –objects, classification hierarchies supporting mechanisms –classes, encapsulation, polymorphism… allows us to –make code look like the design –improves design and code modularity many other benefits build on these
7
CASCON 2004 7 class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; display.update(this); } void setY(int y) { this.y = y; display.update(this); } fair design modularity but poor code modularity 1 Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) * But some concerns “don’t fit” i.e. a simple Observer pattern
8
CASCON 2004 8 aspect ObserverPattern { private Display Shape.display; pointcut change(): call(void figures.Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Shape.moveBy(int, int)); after(Shape s) returning: change() && target(s) { s.display.update(); } } ObserverPattern 1 Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) * With AOP they do fit good design modularity good code modularity
9
CASCON 2004 9 aspect ObserverPattern { private Display Shape.display; pointcut change(): call(void Shape.moveBy(int, int)) || call(void Shape+.set*(..)); after(Shape s) returning: change() && target(s) { s.display.update(); } } ObserverPattern 1 Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) * Ask yourself: could you name a single class “ObserverPattern” ? Code looks like the design
10
CASCON 2004 10 What is AOP? a learned intuitive way of thinking design concepts –aspects, crosscutting structure supporting mechanisms –join points, pointcuts, advice… allows us to –make code look like the design –improve design and code modularity
11
CASCON 2004 11 Today, We All Intuitively See Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) *
12
CASCON 2004 12 Today, We All Intuitively See operations that change shapes factory methods Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) *
13
CASCON 2004 13 AOP Developers Intuitively See… Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) * FactoryEnforcement ObserverPattern BoundsChecking
14
CASCON 2004 14 Mini-outline – next 15 minutes Explain how this AOP code works –Using AspectJ, leading AOP language Pointcuts-and-advice –dynamic join points, pointcuts, advice Inter-type declarations Multiple versions of ObserverPattern IDE demonstration Evaluating modularity –comparing AOP and non-AOP code
15
CASCON 2004 15 Method Execution Join Points :Point method execution join point the entry/exit to the execution not the source code setX(int)
16
CASCON 2004 16 More Method Execution Join Points :Lineend1:Point moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point
17
CASCON 2004 17 Method Call Join Points :Lineend1:Point moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point
18
CASCON 2004 18 Dynamic Join Points all dynamic join points on this slide are within the control flow of this dynamic join point :Lineend1:Point moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point well-defined points in flow of execution
19
CASCON 2004 19 execution(void Line.setP1(Point)) Pointcuts a pointcut is a predicate on dynamic join points that: –can match or not match any given join point –says “what is true” when the pointcut matches –can optionally expose some of the values at that join point a means of identifying dynamic join points matches method execution join points with this signature
20
CASCON 2004 20 Pointcut Composition whenever a Line executes a “void setP1(Point)” or “void setP2(Point)” method or a “void Line.setP2(Point)” execution a “void Line.setP1(Point)” execution execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); pointcuts compose like predicates, using &&, || and !
21
CASCON 2004 21 Primitive Pointcuts -call, execution -get, set -handler -initialization, staticinitialization -within, withincode -this, target, args -cflow, cflowbelow
22
CASCON 2004 22 User-Defined Pointcuts user-defined (aka named) pointcuts –can be used in the same way as primitive pointcuts defined with pointcut declaration pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); nameparameters more on parameters and how pointcut can expose values at join points in a few slides
23
CASCON 2004 23 pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); after() returning: change() { } After Advice a means of affecting semantics at dynamic join points :Line setP1(int) after advice runs on the way back out
24
CASCON 2004 24 A Simple Aspect an aspect defines a special class that can crosscut other classes ObserverPattern v1 box means complete running code aspect ObserverPattern { pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); after() returning: change() { Display.update(); }
25
CASCON 2004 25 Pointcuts can cut across multiple classes pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int));
26
CASCON 2004 26 Pointcuts can use interface signatures pointcut change(): execution(void Shape.moveBy(int, int)) || execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int));
27
CASCON 2004 27 A Multi-Class Aspect ObserverPattern v2 aspect ObserverPattern { pointcut change(): execution(void Shape.moveBy(int, int)) || execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int)); after() returning: change() { Display.update(); }
28
CASCON 2004 28 Using a Naming Convention ObserverPattern v2b aspect ObserverPattern { pointcut change(): execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*)); after() returning: change() { Display.update(); }
29
CASCON 2004 29 pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*)); after(Shape s) returning: change(s) { } Values at Join Points pointcut can explicitly expose certain values advice can use explicitly exposed values demonstration, not detailed explanation parameter mechanism being used
30
CASCON 2004 30 Revised Aspect ObserverPattern v3 aspect ObserverPattern { pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*))); after(Shape s): change(s) { Display.update(s); }
31
CASCON 2004 31 aspect ObserverPattern { private Display Shape.display; static void setDisplay(Shape s, Display d) { s.display = d; } pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*))); after(Shape shape): change(shape) { shape.display.update(s); } One Display per Shape ObserverPattern v4 inter-type declarations declares members of other types –fields, methods
32
CASCON 2004 32 aspect ObserverPattern { private Display Shape.display; static void setDisplay(Shape s, Display d) { s.display = d; } pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*))); after(Shape shape): change(shape) { shape.display.update(s); } Aspect Can Own Object State ObserverPattern v4 display field –is in objects of type Shape –but belongs to ObserverPattern aspect –so ObserverPattern provide accessors private with respect to aspect
33
CASCON 2004 33 Field Getter/Setter aspect ObserverPattern { private Display Shape.display; static Display getDisplay(Shape s) { return s.display; } static void setDisplay(Shape s, Display d) { s.display = d; } … }... ObserverPattern.getDisplay(shape); ObserverPattern.setDisplay(shape, display); ObserverPattern v4
34
CASCON 2004 34 A 2 nd Join Point Model inter-type declarations –aka introductions –aka open classes for defining methods, fields join points –member declarations means of identifying join points –type patterns and signatures means of effecting join points –declare member
35
CASCON 2004 35 Aspect cuts new interface –through Point and Line DisplayUpdating itself is modular aspect ObserverPattern { private Display Shape.display; public void Shape.setDisplay(Display d) { this.display = d; } pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int) || execution(void Shape+.set*(*))); after(Shape s) returning: change(s) { Display.update(s); } Crosscutting Structure and Interfaces class Line { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
36
CASCON 2004 36 IDE support AJDT (AspectJ Development Tool) An Eclipse Project Goal is JDT-quality AspectJ support –highlighting, completion, wizards… –structure browser immediate outline overview
37
CASCON 2004 37 Modularity Assessment Use a simple evolution scenario
38
CASCON 2004 38 Without AspectJ class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
39
CASCON 2004 39 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; Display.update(); } void setP2(Point p2) { this.p2 = p2; Display.update(); } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; } Without AspectJ ObserverPattern v1
40
CASCON 2004 40 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; Display.update(); } void setP2(Point p2) { this.p2 = p2; Display.update(); } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; Display.update(); } void setY(int y) { this.y = y; Display.update(); } Without AspectJ ObserverPattern v2
41
CASCON 2004 41 Without AspectJ ObserverPattern v3 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; Display.update(this); } void setP2(Point p2) { this.p2 = p2; Display.update(this); } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; Display.update(this); } void setY(int y) { this.y = y; Display.update(this); }
42
CASCON 2004 42 class Shape { private Display display; abstract void moveBy(int, int); } class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; Display.update(this); } void setP2(Point p2) { this.p2 = p2; Display.update(this); } class Point extends Shape {... } Without AspectJ “display updating” is not modular –evolution is cumbersome –changes are scattered –have to track & change all callers –it is harder to think about ObserverPattern v4
43
CASCON 2004 43 With AspectJ class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
44
CASCON 2004 44 With AspectJ aspect ObserverPattern { pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); after() returning: change() { Display.update(); } ObserverPattern v1 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
45
CASCON 2004 45 With AspectJ ObserverPattern v2 aspect ObserverPattern { pointcut change(): execution(void Shape.moveBy(int, int) || execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int)); after() returning: change() { Display.update(); } class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
46
CASCON 2004 46 With AspectJ ObserverPattern v2.5 aspect ObserverPattern { pointcut change(): execution(void Shape.moveBy(int, int) || execution(void Shape+.set*(*)); after() returning: change() { Display.update(); } class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
47
CASCON 2004 47 aspect ObserverPattern { pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int) || execution(void Shape+.set*(*))); after(Shape s) returning: change(s) { Display.update(s); } With AspectJ ObserverPattern v3 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }
48
CASCON 2004 48 ObserverPattern is modular –all changes in single aspect –evolution is modular –it is easier to think about With AspectJ ObserverPattern v4 class Line extends Shape { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; } aspect ObserverPattern { private Display Shape.display; static void setDisplay(Shape s, Display d) { s.display = d; } pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*))); after(Shape shape): change(shape) { shape.display.update(s); }
49
CASCON 2004 49 Modularity Assessment The aspect is –localized –has a clear interface The classes are –better localized (no invasion of updating) Code modularity helps design modularity –simple observer pattern is simple The code looks like the design Forest vs. trees –the crosscutting structure is explicit, clear, modular –the local effects can be made clear by IDE
50
CASCON 2004 50 Review So Far Aspect is a software design concept –supported by mechanisms –a “learned intuitive way of thinking” Mechanisms –Pointcuts and advice dynamic join points, pointcuts, advice –Inter-type declarations Different concepts for different structure of concerns –procedure holds computeRadius, setX… –class holds Point, Line… –aspect holds ObserverPattern… Aspects –modular units of implementation –look like modular units of design –improves design and code
51
CASCON 2004 51 Dynamic Join Points several kinds of dynamic join points –method & constructor execution –method & constructor call –field get & set –exception handler execution –static & dynamic initialization method call method execution :Point setX(int) well-defined points in flow of execution
52
CASCON 2004 52 Only Top-Level Changes ObserverPattern v5 aspect ObserverPattern { pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int))); pointcut topLevelchange(Shape s): change(s) && !cflowbelow(change(Shape)); after(Shape shape) returning: topLevelchange(shape) { Display.update(shape); }
53
CASCON 2004 53 Pre-conditions using before advice aspect BoundsPreConditionChecking { before(int newX): execution(void Point.setX(int)) && args(newX) { check(newX >= MIN_X); check(newX <= MAX_X); } before(int newY): execution(void Point.setY(int)) && args(newY) { check(newY >= MIN_Y); check(newY <= MAX_Y); } private void check(boolean v) { if ( !v ) throw new RuntimeException(); } what follows the ‘:’ is always a pointcut – primitive or user-defined
54
CASCON 2004 54 Design Invariants aspect FactoryEnforcement { pointcut newShape(): call(Shape+.new(..)); pointcut inFactory(): within(Point Shape.make*(..)); pointcut illegalNewShape(): newShape() && !inFactory(); before(): illegalNewShape() { throw new RuntimeError("Must call factory method…“); } Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) *
55
CASCON 2004 55 Design Invariants aspect FactoryEnforcement { pointcut newShape(): call(Shape+.new(..)); pointcut inFactory(): within(Point Shape.make*(..)); pointcut illegalNewShape(): newShape() && !inFactory(); declare error: illegalNewShape(): "Must call factory method to create figure elements."; } Display 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) *
56
CASCON 2004 56 Property-Based Pointcuts Consider code maintenance Another programmer adds a public method i.e. extends public interface – this code will still work Another programmer reads this code “what’s really going on” is explicit aspect PublicErrorLogging { Log log = new Log(); pointcut publicInterface(): call(public * com.acme..*.*(..)); after() throwing (Error e): publicInterface() { log.write(e); } neatly captures public interface of mypackage
57
CASCON 2004 57 Swing Thread Safety [Laddad ’03] public abstract aspect SwingThreadSafetyAspect { abstract pointcut uiMethodCall(); pointcut threadSafeCall(): call(void JComponent.revalidate()) || call(void JComponent.repaint(..)) || call(void add*Listener(EventListener)) || call(void remove*Listener(EventListener)); pointcut excludedJoinPoint(): threadSafeCall() || within(SwingThreadSafetyAspect+) || if(EventQueue.isDispatchThread()); Object around() : uiMethodCall() && !excludedJoinPoint() { /* run in another thread… */ } }
58
CASCON 2004 58 Reusable Patterns abstract aspect ObserverPattern { protected interface Subject { } protected interface Observer { } public void addObserver(Subject s, Observer o) {... } public void removeObserver(Subject s, Observer o) {... } public List getObservers(Subject s) {... } abstract pointcut change(Subject s); after(Subject s): change(s) { Iterator iter = getObservers(s).iterator(); while ( iter.hasNext() ) { notifyObserver(s, ((Observer)iter.next())); } abstract void notifyObserver(Subject s, Observer o); } [Hanneman OOPSLA’02]
59
CASCON 2004 59 Concrete Reuse aspect DisplayUpdating extends ObserverPattern { declare parents: FigureElement implements Subject; declare parents: Display implements Observer; pointcut change(Subject s): target(s) && (call(void FigureElement.moveBy(int, int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Point.setX(int)) || call(void Point.setY(int))); void notifyObserver(Subject s, Observer o) { ((Display)o).update(s); } [Hanneman OOPSLA’02]
60
CASCON 2004 60 vm_fault vm_pager_getpages vnode_pager_getpages ffs_getpages … ufs_bmap Path Specific Customization ffs_valid ffs_calc_size [Coady AOSD’03]
61
CASCON 2004 61 Other Aspects Security –pointcut for when checking happens –makes invariant clear, enforced Optimization Distribution Synchronization Persistence and of course, Logging –IBM story and very many application-specific aspects –i.e. EnsureLiveness
62
CASCON 2004 62 Benefits of AOP All the usual modularity benefits –clarity –reusability –quality –easier to develop –configuration management –product line management –IP management –testing –…
63
CASCON 2004 63 Use Cases Each use case is realized by a collaboration - a set of classes A class plays different roles in different use case realizations The total responsibility of a class is the composition of these roles Withdraw Cash Deposit Funds Transfer Funds Cash Withdrawal Cash Interface Cash Interface Deposit Funds Transfer Funds Interface Funds Deposit Cash Transfer Funds Cash Withdrawal Use case Specification Use case design Component design & implementation
64
CASCON 2004 64 More Existing Crosscutting join points –method call reception return aStateChange() _aStateChange() notify() update() SubjectObserver
65
CASCON 2004 65 Industry Adoption AOP adoption is happening very fast Enterprise Java is most active domain –AspectWerkz, JBoss (JavaAssist), Spring, … –IBM actively using AspectJ in Websphere … –BEA, Oracle actively evaluating –Hot topic at TSS Symposium and JavaOne And this year… –Danny Sabbah (IBM VP) commits to AOP in 3 of 5 main product lines –Gates says Microsoft will adopt AOP
66
CASCON 2004 66 Summary AOP is a learned intuitive way of thinking –aspects, crosscutting structure Supporting mechanisms –join points, pointcuts, advice, inter-type declarations Allows us to –make code look like the design –improve design and code modularity A practical way to improve your –software designs, code, product, productivity
67
CASCON 2004 67 Composition Patterns [Clarke, Walker] AOP support in UML Subject + addObserver(Object) + removeObserver(Object) + aStateChange(..) # _aStateChange(..) - notify() subjects * Vector observers 1 Observer + update() + start(..,Subject,..) # _start(..,Subject,..) + stop(..,Subject,..) # _stop(..,Subject,..) «subject» Observer
68
CASCON 2004 68 Aspect Enabled Refactoring Mockup
69
CASCON 2004 69 Fluid Aspects
70
CASCON 2004 70 Fluid Aspects
71
CASCON 2004 71 All Kinds of Crosscutting aStateChange() _aStateChange() notify() update() SubjectObserver
72
CASCON 2004 72 pointcut entry(): !within(com.acme.product..*) && call(public * com.acme.product..*(..)); pointcut initialEntry(): entry() && !cflowbelow(entry()); around(): initialEntry() { proceed(); } Compositional Crosscutting package structure wrt control flow
73
CASCON 2004 73 Limits of Current JP Mechanisms but –if you add a new field for color –you have to extend this pointcut so… after(): call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void FigureElement.moveBy(int, int)) { Display.update(); } it is still it is better than without AOP the dependence is explicit, localized, modular & clear declarative interface (the structure of the crosscutting concern is explicit)
74
CASCON 2004 74 A More Powerful Pointcut robust against some edits the abstraction of the pointcut is now more clear but –if you add a field that doesn’t have a set method –you still have to update the pointcut so… –you could solve this problem by prohibiting wildcards? –you could solve this problem by requiring tags on methods? –NO! solve it by making the means of identifying JPs more precise after(): call(void FigureElement+.set*(..)) || call(void FigureElement.moveBy(int, int)) { Display.update(); }
75
CASCON 2004 75 A More Semantic Pointcut predict the control flow of FigureElement.draw() sets to such fields require display update find fields referenced in that control flow pointcut* displayState(): pcflow(execution(void FigureElement+.draw()) && get(* FigElt+.*); after set( ) (): { Display.update(); }
76
CASCON 2004 76 Other More Semantic Pointcuts dflow(, ) –did the value of the variable come in a dataflow through [Masuhara 04] min(, ) –the least common caller of the two cflows JP mechanism opens a new design space –a language design for packaging such analyses –how to think about programming with them –how to limit to tractable cases
77
CASCON 2004 77 Observer Subject Observer: Display change update: {...} class Point { int x; Getter/Setter int y; void draw() { Graphics.drawOval(…); }... } Superposition of Patterns and Code pattern must be effective (connect to code) ‘wizards’ weave the pattern in but what happens if code changes?
78
CASCON 2004 78 Observer Subject Observer: Display change update: {...} class Point { int x; Getter/Setter int y; void draw() { Graphics.drawOval(…); }... } Making ‘Generators’ Work Together Observer can refer to expansion of Getter/Setter –clearly, reliably, stably –alternate reference, beyond causal reach, indexical multiple routes to reference beyond causal reach indexical
79
CASCON 2004 79 1.use pointcut to identify scattered aspect 2.shows up below 3.delete them all 4.rewrite with advice
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.