142
Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved. www.parc.xerox.com/ aop

Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Embed Size (px)

Citation preview

Page 1: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Aspect-Oriented Programming w/AspectJ™

Cristina Lopes, Gregor Kiczales

Xerox PARC

© Copyright 1998, Xerox Corporation. All Rights Reserved.

www.parc.xerox.com/aop

Page 2: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

2

• using AOP and AspectJ to:– improve the design and source code modularity

of systems that involve cross-cutting concerns

• aspects are:– a new kind of programming construct, that

• supports a new kind of module• enables concerns that cross-cut the system to be

captured in clean units

• AspectJ is:– is an aspect-oriented extension to Java™ that

supports general-purpose aspect programming

this tutorial is about...

Page 3: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

3

an example systema distributed digital library

Page 4: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

4

clean modular design

title: stringauthor: stringisbn: intpdf: pdftiff: tiff

LibraryBookholds* *

cooperates**

User

accesses

*

*

Printeruses* *

Page 5: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

5

public class PrinterImpl { String status = “Idle” Vector jobs;

public PrinterImpl() {} pubilc get_status() { return status } public add_job(int j) { jobs.add(j); }}

Book

Printer

User Libraryclass Library { Hashtable books; Library(){ books = new Hashtable(100); } public Book getBook(User u, String title) { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b; } } return null; }}

class User { private String name; Library theLibrary; Printer thePrinter;

public User(String n) { name = n; }

public boolean getBook (String title) { Book aBook = theLibrary.getBook(this, title); thePrinter.print(this,aBook); return true; }}

class Book { private String title; private String author; private String isbn; private PostScript ps; private User borrower;

public Book(String t, String a, String i, PostScript p) { title = t; author = a; isbn = i; ps = p; }

public User get_borrower() {return borrower;} public void set_borrower(User u) {borrower = u;} public PostScript get_ps() { return ps; }}

clean modular code

Page 6: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

6

benefits of good modularity

• aka “clean separation of concerns”• each decision in a single place

– easy to understand– easy to modify– easy to unplug

Page 7: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

7

but...

• some issues don’t localize to objects– global coordination– interactions among many objects– resource sharing– error handling– performance optimizations– synchronization– . . .

Page 8: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

8

Book

Printer

User Libraryclass Book { private BookID id; private PostScript ps; private UserID borrower;

public Book(String t, String a, String i, PostScript p) { id = new BookID(t,a,i); ps = p; }

public UserID get_borrower() {return borrower;} public void set_borrower(UserID u) {borrower = u;} public PostScript get_ps() { return ps; } public BookID get_bid() { return id; }}

class BookID { private String title; private String author; private String isbn;

public BookID(String t, String a, String i) { title = t; author = a; isbn = i; } public String get_title() {return title;}}

class User { private UserID id; Library theLibrary; Printer thePrinter;

public User(String n) { id = new UserID(n); }

public boolean getBook (String title) { BookID aBook=null; try{ aBook = theLibrary.getBook(id, title); } catch (RemoteException e) {} try { thePrinter.print(id, aBook); } catch (RemoteException e) {} return true; } public UserID get_uid() { return id; }}

class UserID { private String name;

public UserID(String n) { name = n; } public String get_name() { return name; }}

interface LibraryInterface extends Remote { public BookID getBook(UserID u, String title) throws RemoteException;

public PostScript getBookPS(BookID bid) throws RemoteException;}

class Library extends UnicastRemoteObject implements LibraryInterface { Hashtable books; Library() throws RemoteException { books = new Hashtable(100); } public BookID getBook(UserID u, String title) throws RemoteException { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b.get_bid(); } } return null; } public PostScript getBookPS(BookID bid) throws RemoteException { if (books.containsKey(bid.get_title())) { Book b = (Book)books.get(bid.get_title()); if (b != null) return b.get_ps(); } return null; }

}

interface PrinterInterface extends Remote { public boolean print (UserID u, BookID b) throws RemoteException;}

public class Printer extends UnicastRemoteObject implements PrinterInterface { private Vector jobs = new Vector(10, 10); private Library theLibrary;

public Printer() throws RemoteException{} public boolean print (UserID u, BookID b) throws RemoteException{ PostScript ps=null; try{ ps = theLibrary.getBookPS(b); } catch (RemoteException e) {} Job newJob = new Job (ps, u); return queue(newJob); } boolean queue(Job j) { //... return true; }}

digital library with optimization

Page 9: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

9

Book

Printer

User Libraryclass Book { private BookID id; private PostScript ps; private UserID borrower;

public Book(String t, String a, String i, PostScript p) { id = new BookID(t,a,i); ps = p; }

public UserID get_borrower() {return borrower;} public void set_borrower(UserID u) {borrower = u;} public PostScript get_ps() { return ps; } public BookID get_bid() { return id; }}

class BookID { private String title; private String author; private String isbn;

public BookID(String t, String a, String i) { title = t; author = a; isbn = i; } public String get_title() {return title;}}

class User { private UserID id; Library theLibrary; Printer thePrinter;

public User(String n) { id = new UserID(n); }

public boolean getBook (String title) { BookID aBook=null; try{ aBook = theLibrary.getBook(id, title); } catch (RemoteException e) {} try { thePrinter.print(id, aBook); } catch (RemoteException e) {} return true; } public UserID get_uid() { return id; }}

class UserID { private String name;

public UserID(String n) { name = n; } public String get_name() { return name; }}

interface LibraryInterface extends Remote { public BookID getBook(UserID u, String title) throws RemoteException;

public PostScript getBookPS(BookID bid) throws RemoteException;}

class Library extends UnicastRemoteObject implements LibraryInterface { Hashtable books; Library() throws RemoteException { books = new Hashtable(100); } public BookID getBook(UserID u, String title) throws RemoteException { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b.get_bid(); } } return null; } public PostScript getBookPS(BookID bid) throws RemoteException { if (books.containsKey(bid.get_title())) { Book b = (Book)books.get(bid.get_title()); if (b != null) return b.get_ps(); } return null; }

}

interface PrinterInterface extends Remote { public boolean print (UserID u, BookID b) throws RemoteException;}

public class Printer extends UnicastRemoteObject implements PrinterInterface { private Vector jobs = new Vector(10, 10); private Library theLibrary;

public Printer() throws RemoteException{} public boolean print (UserID u, BookID b) throws RemoteException{ PostScript ps=null; try{ ps = theLibrary.getBookPS(b); } catch (RemoteException e) {} Job newJob = new Job (ps, u); return queue(newJob); } boolean queue(Job j) { //... return true; }}

“cross-cutting”

this optimization cross-cuts the primary structure of the program

Page 10: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

10

effects of cross-cutting

• “tangled code”• code duplication,• difficult to reason about

– why is this here?– what does this connect to?– difficult to make changes

• essentially, it destroys modularity

Page 11: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

11

the AOP idea

• many cross-cuts aren’t random!– they serve specific purposes:

• performance optimizations, interactions among objects, enforcing consistency, tracking global state…

– they have well-defined structure:• lines of dataflow, boundary crossings, points

of resource utilization, points of access…

• so… let’s capture the cross-cutting structure in a modular way...

Page 12: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

12

class User { private UserID id; Library theLibrary; Printer thePrinter;

public User(String n) { id = new UserID(n); }

public boolean getBook (String title) { BookID aBook=null; try{ aBook = theLibrary.getBook(id, title); } catch (RemoteException e) {} try { thePrinter.print(id, aBook); } catch (RemoteException e) {} return true; } public UserID get_uid() { return id; }}

class UserID { private String name;

public UserID(String n) { name = n; } public String get_name() { return name; }}

interface LibraryInterface extends Remote { public BookID getBook(UserID u, String title) throws RemoteException;

public PostScript getBookPS(BookID bid) throws RemoteException;}

class Library extends UnicastRemoteObject implements LibraryInterface { Hashtable books; Library() throws RemoteException { books = new Hashtable(100); } public BookID getBook(UserID u, String title) throws RemoteException { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b.get_bid(); } } return null; } public PostScript getBookPS(BookID bid) throws RemoteException { if (books.containsKey(bid.get_title())) { Book b = (Book)books.get(bid.get_title()); if (b != null) return b.get_ps(); } return null; }

}

interface PrinterInterface extends Remote { public boolean print (UserID u, BookID b) throws RemoteException;}

public class Printer extends UnicastRemoteObject implements PrinterInterface { private Vector jobs = new Vector(10, 10); private Library theLibrary;

public Printer() throws RemoteException{} public boolean print (UserID u, BookID b) throws RemoteException{ PostScript ps=null; try{ ps = theLibrary.getBookPS(b); } catch (RemoteException e) {} Job newJob = new Job (ps, u); return queue(newJob); } boolean queue(Job j) { //... return true; }}

class Book { private BookID id; private PostScript ps; private UserID borrower;

public Book(String t, String a, String i, PostScript p) { id = new BookID(t,a,i); ps = p; }

public UserID get_borrower() {return borrower;} public void set_borrower(UserID u) {borrower = u;} public PostScript get_ps() { return ps; } public BookID get_bid() { return id; }}

class BookID { private String title; private String author; private String isbn;

public BookID(String t, String a, String i) { title = t; author = a; isbn = i; } public String get_title() {return title;}}

public class PrinterImpl { String status = “Idle” Vector jobs;

public PrinterImpl() {} pubilc get_status() { return status } public add_job(int j) { jobs.add(j); }}

class Library { Hashtable books; Library(){ books = new Hashtable(100); } public Book getBook(User u, String title) { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b; } } return null; }}

class User { private String name; Library theLibrary; Printer thePrinter;

public User(String n) { name = n; }

public boolean getBook (String title) { Book aBook = theLibrary.getBook(this, title); thePrinter.print(this,aBook); return true; }}

class Book { private String title; private String author; private String isbn; private PostScript ps; private User borrower;

public Book(String t, String a, String i, PostScript p) { title = t; author = a; isbn = i; ps = p; }

public User get_borrower() {return borrower;} public void set_borrower(User u) {borrower = u;} public PostScript get_ps() { return ps; }}

portal Printer { void print(Book book) { book: Book: {direct pages;}

}portal Library { Book find (String title){ return: Book: {copy title, author, isbn;} }}

this aspect localizes the cross-cutting in one place

aspects: a cross-cutting module

Page 13: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

13

aspect-oriented programming

• “aspects” are program constructs that cross-cut classes1 in well-defined, principled ways– the programmer uses classes to

implement the primary module structure– the programmer uses aspects to

implement the cross-cutting module structure

1 or other appropriate primary program construct, i.e. procedures if you added AOP to Scheme

Page 14: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

14

aspect weaving

• weaver combines classes and aspects– compiler / pre-processor / interpreter– unambiguously coordinates cross-cutting

aspect weaver

public class PrinterImpl { String status = “Idle” Vector jobs;

public PrinterImpl() {} pubilc get_status() { return status } public add_job(int j) { jobs.add(j); }}

class Library { Hashtable books; Library(){ books = new Hashtable(100); } public Book getBook(User u, String title) { System.out.println("REQUEST TO GET BOOK " + title); if(books.containsKey(title)) { Book b = (Book)books.get(title); System.out.println("getBook: Found it:" + b); if (b != null) { if (b.get_borrower() == null) b.set_borrower(u); return b; } } return null; }}

class User { private String name; Library theLibrary; Printer the; Printer

public User(String n) { name = n; }

public boolean getBook (String title) { Book aBook = theLibrary.getBook(this, title); thePrinter.print(this,aBook); return true; }}

class Book { private String title; private String author; private String isbn; private PostScript ps; private User borrower;

public Book(String t, String a, String i, PostScript p) { title = t; author = a; isbn = i; ps = p; }

public User get_borrower() {return borrower;} public void set_borrower(User u) {borrower = u;} public PostScript get_ps() { return ps; }}

portal Printer { void print(Book book) { book: Book: {direct pages;}

}

portal Library { Book find (String title){ return: Book: {copy title, author, isbn;} }}

classes

aspects

executable code

Page 15: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

15

benefits of using AOP

• good modularity, even in the presence of cross-cutting concerns– less tangled code, more natural code,

smaller code– easier maintenance and evolution

• easier to reason about, debug, change

– more reusable• plug and play

Page 16: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

16

AspectJ™ is…

• the first general-purpose AO language– “lexical” cross-cutting (current)– concern-specific libraries (current)– other kinds of cross-cutting (future)

• an extension to Java• freely available implementation

– user community will drive future design

Page 17: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

17

looking ahead

• AOP works because cross-cutting modularities aren’t random

• aspects are used to capture the structure of the cross-cutting in clean ways

AspectJ mechanisms Part II:

the kinds of cross-cutting mechanisms AspectJ can capture

problem structure Part IV:

how to use AspectJ to capture the higher-level cross-cutting in your systems

Page 18: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

18

outline• I AOP overview

– motivation, what is the AOP idea

• II AspectJ overview– basic concepts, kinds of cross-cutting

• III key technical details– running the aspect weaver, source files, emacs support

• IV using AspectJ– more realistic examples, kinds of aspects, elaboration of

language semantics

• V style issues– when to use aspects, aspect coding style issues

• VI related work– survey of other activities in the AOP world

Page 19: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Part IIBasic Concepts of AspectJ

Page 20: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

20

goals of this chapter

• present the basic concepts of AspectJ– the different kinds of cross-cutting– when aspect code runs– what context aspect code runs in

• using a single simple example

• the next chapters elaborate on– environment, tools– details of the semantics– what can be written using AspectJ

Page 21: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

21

overview

class instances

code (methods)and some state

state

whereas the underlying Java™ language supports classes and objects

Page 22: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

22

overview

class

aspect

AspectJ extends this with aspects that cross-cut the code in classes in various ways…

Page 23: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

23

overview

class class

aspect

AspectJ extends this with aspects that cross-cut the code in classes in various ways…

Page 24: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

24

overview

class class

aspect aspect

AspectJ extends this with aspects that cross-cut the code in classes in various ways…

Page 25: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

25

overview

class class

aspect aspect

and aspect instances that cross-cut the state in objects in various ways

Page 26: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

26

a first example

class Point { int _x = 0; int _y = 0;

void set (int x, int y) { _x = x; _y = y; }

void setX (int x) { _x = x; }

void setY (int y) { _y = y; }

int getX() { return _x; }

int getY() { return _y; }}

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

Page 27: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

27

what it does

Point p1 = new Point();Point p2 = new Point();

p1p2

The screen

p1.set(3, 3); W

Wp2.setX(3);

Page 28: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

28

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

Point

ShowAccesses

one aspect, one class

this “advise weave” affects several methods in the class

static: no aspect instances involved

before: do this before method body

Page 29: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

29

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

presentation note!

the syntax shown here is slightly simplified, mostly to save room on the slides

the full syntax for advise weaves on methods is presented in part iv

(also look at the SpaceWar code)

Page 30: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

30

class Point { int _x = 0; int _y = 0;

void set (int x, int y) { System.out.println(“W”); _x = x; _y = y; } void setX (int x) { System.out.println(“W”); _x = x; } void setY (int y) { System.out.println(“W”); _y = y; } . .

here’s what we would have had to write in plain Java

without AspectJ

• what was in one place is instead in 3

• what was separated is now mixed in

Page 31: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

31

Point p1 = new Point();Point p2 = new Point();

p1p2

The screen

p1.set(3, 3); W

Wp2.setX(3);

Rint x = p1.getX();

extend to writes and reads...

Page 32: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

32

one aspect with two weaves

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

Point

just as a class can have n methods

an aspect can have n weaves

ShowAccessesaspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); } static before Point.getX, Point.getY,{ System.out.println(“R”); }}

Page 33: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

33

one aspect, two classes

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

Point

ShowAccessesaspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); } static before Line.set, Line.setX1, ... { System.out.println(“W”); }}

Line

Page 34: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

34

one aspect, two classes

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY { System.out.println(“W”); }}

Point

ShowAccesses

Line

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY, Line.set, Line.setX1, ... { System.out.println(“W”); }}

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY, Line.set, Line.setX1, ... { System.out.println(“W”); } static before Point.getX, Point.getY, Line.getX1, ... { System.out.println(“R”); } }

Page 35: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

35

reads, writes and constructorsaspect ShowAccesses { static before Point.set, Point.setX, Point.setY Line.set, Line.setX1, ... { System.out.println(“W”); } static before Point.getX, Point.getY, Line.getX1, ... { System.out.println(“R”); } static before Point(*), Line(*) { System.out.println(“C”); } }

methods

constructors

Page 36: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

36

summary so far

ShowAccesses

Pointone aspect, one class

ShowAccesses

Pointone aspect, two classes

Line

static advise weaves allow aspect to:

• extend existing class definitions independent of any aspect instances

• by modifying existing methods/constructors

• nxm cross-cutting is coming up

Page 37: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

37

aspects are special classesclass Point { … }

class Line { … }

class Circle { … }

aspect LogNewInstances { static DataOutputStream log = null; static { // initializer try { log = new DataOutputStream( new FileOutputStream(“log”)); } catch (IOException e) {} } static after Point(*), Line(*), Circle(*) { long time = System.currentTimeMillis(); try { log.writeBytes(“New instance at ” + time + “ ” + thisObject.toString() + “\n”); } catch (IOException e) {} }}

LogNewInstances

Point

Line

Circle

the objectaspect var

Page 38: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

38

what it does

Point p1 = new Point(); p1

New instance at 3252384 Point321

p2

New instance at 3252451 Point322

Point p2 = new Point();

l1

New instance at 3252653 Line611

Line l1 = new Line();l2

New instance at 3255678 Line612

Line l2 = new Line();l3

New instance at 3258765 Line613

Line l3 = new Line();c1

New instance at 4532805 Circle901

Circle c1 = new Circle();

Page 39: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

39

per-object aspect-related state

make Points go back to 0,0 after every 100 sets

Point

AutoReset

aspect AutoReset { static new int Point.count = 0; static after Point.set, Point.setX, Point.setY { if ( ++count >= 100 ) { count = 0; _x = 0; _y = 0; } }}

“new weaves” add definitions

• new fields, methods and constructors

• must be static

object’s scope

available

Page 40: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

40

a peek ahead to style issues

make Points go back to 0,0 after every 100 sets

Point

AutoReset

aspect AutoReset { static new int Point.count = 0; static after Point.set, Point.setX, Point.setY { if ( ++count >= 100 ) { count = -1; set(0, 0); } }}

“new weaves” add definitions

• new fields, methods and constructors

• must be static

what is the class /

aspect inferace?

Page 41: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

41

how this runs

count=0

Point p1 = new Point(); p1

count=0

Point p2 = new Point(); p2

p2.setY(7);

count=1

p1.set(3, 3);

count=1

p1.setX(3);

count=2

Page 42: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

42

summary so farShowAccesses

Pointn aspects, m classes

Line

Point

AutoReset

adding state to each object

• advise weaves allow aspect to modify existing class definitions

• new weaves allow aspect to add to existing class definitions

• static means independent of any aspect instances

• nxm cross-cutting

Page 43: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

43

aspect instances

Point

AutoReset

aspect can be instantiated and aspect instances can then be

associated with objects

as a first step, move the counter from objects to

aspect instances

Page 44: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

44

simple use of aspect instancesaspect AutoReset { int count = 0; after Point.set, Point.setX, Point.setY { if (++count >= 100) { count = -1; set(0, 0); } }}

non-static

not a weave

Page 45: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

45

what it does

Point p1 = new Point(); p1

Point p2 = new Point(); p2

AutoReset a1 = new AutoReset();

count=0

a1.addObject(p1);

count=0

AutoReset a2 = new AutoReset();

a2.addObject(p2);

p1.set(3, 3);

count=1

p1.setX(3);

count=2

p2.setY(7);

count=1

after instantiation of every Point object, instantiate an

AutoReset aspect and associate the two

Page 46: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

46

one aspect instance, many objects

Point p1 = new Point(1, 1);

p1

Point p2 = new Point(1, 1);

p2

Point p3 = new Point(1, 1);

p3a1.addObject(p1);

a1.addObject(p3);

a1.addObject(p2);

the goal here is to get all of the Points to share a single AutoReset counter, so that they all reset, when as a group they have been set 100 times

AutoReset a1 = new AutoReset();

Page 47: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

47

one aspect instance, many objects

aspect AutoReset { int count = 0; after Point.set, Point.setX, Point.setY { if (++count >= 100) { Vector objects = thisAspect.getObjects(); Enumeration e = objects.elements(); while (e.hasMoreElements()) { Point p = (Point)e.nextElement(); count = -1; p.set(0, 0); } } }}

aspect.getObjects() returns a vector of the objects

object.getAspects() returns a vector of the aspects

Page 48: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

48

aspects compose

Line

ShowAccesses

Point Circle

LogNewInstances

AutoReset

• all three aspects apply to the class Point– more on controlling this in next part

• code retains good separation of concerns

Page 49: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

49

here’s the complete code written with AspectJ

with AspectJclass Point { int _x = 0; int _y = 0;

void set (int x, int y) { _x = x; _y = y; }

void setX (int x) { _x = x; }

void setY (int y) { _y = y; }

int getX() { return _x; }

int getY() { return _y; }}

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY Line.set, Line.setX1, ... { System.out.println(“W”); } static before Point.getX, Point.getY, Line.getX1, ... { System.out.println(“R”); } static before Point(*), Line(*) { System.out.println(“C”); } }

aspect LogNewInstances { static DataOutputStream log = null; static { // initializer try { log = new DataOutputStream( new FileOutputStream(“log”)); } catch (IOException e) {} } static after Point(*), Line(*), Circle(*) { long time = System.currentTimeMillis(); try { log.writeBytes(“New instance at ” + time + “ ” + this.toString() + “\n”); } catch (IOException e) {} }}

aspect AutoReset { int counter = 0; after Point.set, Point.setX, Point.setY { if (++counter >= 100) { count = -1; set(0, 0); } }}

Page 50: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

50

class Point { int _x = 0; int _y = 0;

Point () { System.out.println("C"); long time = System.currentTimeMillis(); try { log.writeBytes("New instance at " + time +

" " + Point.this.toString() + "\n"); } catch (IOException e) { } }

void set(int x, int y) { System.out.println("W"); _x = x; _y = y; doAutoResets(); }

void setX(int x) { System.out.println("W"); _x = x; doAutoResets(); }

void setY(int y) { System.out.println("W"); _y = y; doAutoResets();

}

int getX() { System.out.println("R"); return _x; }

int getY() { System.out.println("R"); return _y; }

here’s a well-written version of what we would have had to write in plain Java

without AspectJ

Vector autoResets = new Vector(); void doAutoResets() { java.util.Enumeration enumeration = autoResets.elements(); AutoReset reset; while (enumeration.hasMoreElements()) { reset = (AutoReset)enumeration.nextElement();

if(++ reset.count >= 100){ System.out.println("Reseting " + this + "."); reset.count = - 1; set(0,0);}

} }

static DataOutputStream log = null; static { try { log = new DataOutputStream(new FileOutputStream("log")); } catch (IOException e) { } } }

class AutoReset { int count = 0; public void addToScope(Point object) { object.autoResets.addElement(this); } public void removeFromScope(Point object) { object.autoResets.removeElement(this); } }

Page 51: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

51

benefits of using AOP

• good modularity, even in the presence of cross-cutting concerns– less tangled code, more natural code,

smaller code– easier maintenance and evolution

• easier to reason about, debug, change

– more reusable• plug and play

Page 52: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

52

summary

• advise weaves, new weaves• different kinds of cross-cutting

static and non-static• weave code runs in mixed scope

Line

ShowAccesses

PointCircle

LogNewInstances

AutoReset

Page 53: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

53

looking ahead

• AOP works because cross-cutting modularities aren’t random

• aspects are used to capture the structure of the cross-cutting in clean ways

AspectJ mechanisms Part II: the low-level kinds of cross-

cutting AspectJ can capture

problem structure Part III: how to use AspectJ to capture

the higher-level kinds of cross-cutting in your systems

Page 54: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Part IIIUsing AspectJ, the tool

Page 55: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

55

source files

Point

ShowAccess

“.ajava” files contain:

• regular Java source code• aspect source code

Page 56: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

56

processing aspects

Point

ShowAccess

aspectweaver

.ajava files

bytecode

.classfiles

Page 57: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

57

intermediate files

Point

ShowAccess

aspectweaver

.ajava files

bytecode

.classfiles

.javafiles

Javacode

pre-processor:• simplicity• transition strategy

Page 58: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

58

programming environment

• source files– extension– contents

• look&feel of ajava mode for emacs– what aspects apply where

• weaving• woven code and tracking errors

Page 59: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

59

demo of the AspectJ tools

Page 60: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Part IV - Using Aspects

AspectJ mechanisms Part II:

the kinds of cross-cutting mechanisms AspectJ can capture

problem structure Part IV:

how to use AspectJ to capture the higher-level cross-cutting in your systems

Page 61: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

61

purpose and structure

• styles of aspects presented with examples:– common implementations

– interaction (protocols)

– shared state

– specialized aspect libraries

interleavedwithmore detailaboutAspectJ

Page 62: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

62

notation

Class object

Aspect

Interface

aspectinstance

slide containingsemantic rulesor conventions

piece of implementation

Page 63: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

63

terminology

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY Line.set, Line.setX1, ... { System.out.println(“W”); }}

designators

weave mode

weave declaration(“weave”, for short)

this syntax is slightly simplified, mostly to save room on the slides

see next slide for the full syntax for designators

Page 64: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

64

designators

• methods: ResultType Type.Id ( Formals )

• constructors: Type ( Formals )

• initializers: Type

• fields: Type.Id

examples:

void Point.set(int x, int y) * Point.set(*) shapes.util.Point(*) Point(int x, int y) shapes.Point.x

methods

field

constructors

ResultType: Type | *Formals: TrueFormals | *

Page 65: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

65

outline

• using aspects to localize :– common implementations– interaction (protocols)– shared state

• specialized aspect libraries

Page 66: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

66

example: plug & play tracing

want to print out a trace message before and afterevery method of these classes;want to be able to turn it off

class Customer { … }

class Order { … }

class Product { … }

Page 67: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

67

with an aspect

Customer

Order

Product

aspect Trace { static before * Customer.*(*), * Order.*(*), * Product.*(*) { System.out.println(“ENTERING ” + thisMethodID); }

static after * Customer.*(*), * Order.*(*), * Product.*(*) { System.out.println(“EXITING ” + thisMethodID); }

}

Page 68: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

68

plug and play (plug and debug)

• plug in:

• plug out:

– turn debugging on/off without editing classes

– debugging disabled with no runtime cost– can save debugging code between uses

ajweaver Customer.ajava Order.ajava Product.ajava Trace.ajava

ajweaver Customer.ajava Order.ajava Product.ajava

Page 69: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

69

special vars, scope rules

• specials:– thisAspect– thisObject– thisClassName– thisMethodName

• scope rules in body of weaves:1. formals2. aspect3. object

strings

Page 70: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

70

an exception aspect

XeroxServer

Status getStatus()void registerClient(Client c)

in all implementationsof this interface, want to log exceptions

Page 71: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

71

aspect XeroxServerCatcher {

static catch XeroxServer.getStatus, XeroxServer.registerClient (Exception e) { System.err.println(“Exception ” + e + “ at ” + System.currentTimeMillis()); throw e; }}

an exception aspect

type name

aspect XeroxServerCatcher {

static catch XeroxServer.getStatus, XeroxServer.registerClient (Exception e) { System.err.println(“Exception ” + e + “ at ” + System.currentTimeMillis()); throw e; }}

Page 72: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

72

types

• in Java:– Interface = Type (no implementation)– Class = Type + implementation

• designators refer to types– aspects apply to interfaces too!

• weaves apply to all implementations

of the designated types

Page 73: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

73

aspects for interfaces

XeroxServer XeroxServerCatcher

Class1 Class2 Class3 ...

implementsimplementsimplements

XeroxServerCatcher affectsClass1, Class2, Class3, ...

Page 74: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

74

aspects that localize common code

A

B

C

A

B

C

Aspect

used in• set-ups/clean-ups• tracing• logging • method guards• ...

Page 75: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

75

aspects that localize common code

• there is an abstraction occurring in several classes

• this abstraction can be implemented by a common piece of code

• inheritance is not best model or gets in the way of other code reuse

• aspect contains the common piece of code

Page 76: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

76

outline

• using aspects to localize :– common implementations– interaction (protocols)

• aspects as repositories of related implementations

• design patterns

– shared state

• specialized aspect libraries

Page 77: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

77

example: tic-tac-toe

Player

public: run() getTurn() endGame(Player, Result) actionPerformed(ActionEvent) mouseClicked(MouseEvent)protected: addStatusDisplay()

TicTacToe

public: run() startGame() newPlayer(Player) putMark(Player, Position) getBoard() getNPlayers() getCurrentPlayer() isOver() getResult() attach(TTTObserver) detach(TTTObserver)protected: waitForPlayers() waitForMove() endGame() notify() on state changes

TTTObserver

public: actionPerformed(ActionEvent) aboutWindow() update()protected: addMenu() addBoardDisplay() addStatusDisplay() finish()

2

TicTacToe

public: run() startGame() newPlayer(Player) putMark(Player, Position) getBoard() getNPlayers() getCurrentPlayer() isOver() getResult() attach(TTTObserver) detach(TTTObserver)protected: waitForPlayers() waitForMove() endGame() notify() on state changes

TTTObserver

public: actionPerformed(ActionEvent) aboutWindow() update()protected: addMenu() addBoardDisplay() addStatusDisplay() finish()

plus other classes...

Page 78: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

78

view of the update protocol

Player

TicTacToe

public: ... attach(TTTObserver) detach(TTTObserver)protected: notify() on state changes

TTTObserver

public: update()

Canvas

Label

BoardDisplayupdate()

StatusDisplayupdate()

6 tightly relatedmethods andcalls to notify()are spread all over

Page 79: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

79

the protocol in an aspect

TicTacToe

StatusDisplay

TTTObserver

BoardDisplay

aspect TTTDisplayProtocol { static new Vector TicTacToe.observers = new Vector(); static new Tictactoe TTTObserver.game;

static new void TicTacToe.attach(TTTObserver obs) { observers.addElement(obs); } static new void TicTacToe.detach(TTTObserver obs) { observers.removeElement(obs); } static new void TTTObserver.update() { board.update(game); status.update(game); } static new void BoardDisplay.update(TicTacToe game), StatusDisplay.update(TicTacToe game) { theGame = game; repaint(); } // all methods that change state static after TicTacToe.startGame, TicTacToe.newPlayer, TicTacToe.putMark, TicTacToe.endGame { for (int i = 0; i < observers.size(); i++) ((Observer)observers.elementAt(i)).update(); }}

aspect TTTDisplayProtocol { static new Vector TicTacToe.observers = new Vector(); static new Tictactoe TTTObserver.game;

static new void TicTacToe.attach(TTTObserver obs) { observers.addElement(obs); } static new void TicTacToe.detach(TTTObserver obs) { observers.removeElement(obs); } static new void TTTObserver.update() { board.update(game); status.update(game); } static new void BoardDisplay.update(TicTacToe game), StatusDisplay.update(TicTacToe game) { theGame = game; repaint(); } // all methods that change state static after TicTacToe.startGame, TicTacToe.newPlayer, TicTacToe.putMark, TicTacToe.endGame { for (int i = 0; i < observers.size(); i++) ((Observer)observers.elementAt(i)).update(); }}

aspect TTTDisplayProtocol { static new Vector TicTacToe.observers = new Vector(); static new Tictactoe TTTObserver.game;

static new void TicTacToe.attach(TTTObserver obs) { observers.addElement(obs); } static new void TicTacToe.detach(TTTObserver obs) { observers.removeElement(obs); } static new void TTTObserver.update() { board.update(game); status.update(game); } static new void BoardDisplay.update(TicTacToe game), StatusDisplay.update(TicTacToe game) { theGame = game; repaint(); } // all methods that change state static after TicTacToe.startGame, TicTacToe.newPlayer, TicTacToe.putMark, TicTacToe.endGame { for (int i = 0; i < observers.size(); i++) ((Observer)observers.elementAt(i)).update(); }}

aspect TTTDisplayProtocol { static new Vector TicTacToe.observers = new Vector(); static new Tictactoe TTTObserver.game;

static new void TicTacToe.attach(TTTObserver obs) { observers.addElement(obs); } static new void TicTacToe.detach(TTTObserver obs) { observers.removeElement(obs); } static new void TTTObserver.update() { board.update(game); status.update(game); } static new void BoardDisplay.update(TicTacToe game), StatusDisplay.update(TicTacToe game) { theGame = game; repaint(); } // all methods that change state static after TicTacToe.startGame, TicTacToe.newPlayer, TicTacToe.putMark, TicTacToe.endGame { for (int i = 0; i < observers.size(); i++) ((Observer)observers.elementAt(i)).update(); }}

aspect TTTDisplayProtocol { static new Vector TicTacToe.observers = new Vector(); static new Tictactoe TTTObserver.game;

static new void TicTacToe.attach(TTTObserver obs) { observers.addElement(obs); } static new void TicTacToe.detach(TTTObserver obs) { observers.removeElement(obs); } static new void TTTObserver.update() { board.update(game); status.update(game); } static new void BoardDisplay.update(TicTacToe game), StatusDisplay.update(TicTacToe game) { theGame = game; repaint(); } // all methods that change state static after TicTacToe.startGame, TicTacToe.newPlayer, TicTacToe.putMark, TicTacToe.endGame { for (int i = 0; i < observers.size(); i++) ((Observer)observers.elementAt(i)).update(); }}

aspect containsfields, methods and proceduresof protocol

Page 80: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

80

observer pattern

Subject attach(Observer) detach(Observer) notify() on state changes

Observer update()

ConcreteObserverupdate()

ConcreteSubject

• protocol is spread in many classes• not so good in Java - uses up only inheritance link

With inheritance

observers.addElement(obs);

observers.removeElement(obs);

Page 81: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

81

observer pattern

Observerupdate()

ConcreteObserverupdate()

implements

Subjectattach(Observer)detach(Observer)

implements

ConcreteSubject attach(Observer) detach(Observer)notify() on state changes

• protocol is spread in many classes• some replication of code in the concrete subjects

with interfaces

observers.addElement(obs);

observers.removeElement(obs);

Page 82: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

82

observer patternwith aspects

ConcreteObserverimplements

implementsConcreteSubject

• protocol implementation is encapsulated in the aspects

Subjectattach(Observer)detach(Observer)

Observerupdate()

SubjectObserverstatic new Observer.subjectstatic new Subject.observersstatic new Subject.attach(Observer)static new Subject.detach(Observer)

observers.addElement(obs);

observers.removeElement(obs);

ConcreteObserverUpdatesstatic new ConcreteObserver.update()static after ConcreteSubject.m1, ConcreteSubject.m2, ...

for (int i = 0; i < observers.size(); i++) { obs = observers.elementAt(i); obs.update();}

Page 83: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

83

aspects that localize interaction

A

B

C

1

2 3

4 A

B

C

Aspect

used in• multi-class protocols

– GUIs– notification– ...

• many design patterns

Page 84: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

84

aspects that localize interaction

• there is an interaction (protocol) involving several classes

• methods of the protocol are more coupled with each other than with the classes where they “sit”

• aspect captures the whole protocol

Page 85: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

85

outline

• using aspects to localize :– common implementations– interaction (protocols)– shared state

• static vs non-static state• when to use aspect instances

• specialized aspect libraries

Page 86: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

86

static vs. non-staticaspect Count1 { static int count = 0; static before Point.set, Point.setX, Point.setY { count++; }}

aspect Count2 { int count = 0; before Point.set, Point.setX, Point.setY { thisAspect.count++; }}

class Point { int _x = 0; int _y = 0;

void set (int x, int y) { _x = x; _y = y; }

void setX (int x) { _x = x; }

void setY (int y) { _y = y; }

int getX() { return _x; }

int getY() { return _y; }}

Page 87: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

87

static vs. non-static fieldsaspect Count1 { static int count = 0; static before Point.set, Point.setX, Point.setY { count++; }}

one incarnation of count (same as static in class fields)

one incarnation of count per aspect instance(same as non-static in class fields)

Point p0 = new Point(0,0);Point p1 = new Point(1,1);

aspect Count2 { int count = 0; before Point.set, Point.setX, Point.setY { thisAspect.count++; }}

Point p0 = new Point(0,0);Point p1 = new Point(1,1);

Page 88: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

88

static vs. non-static weaves

two issues:

1. objects affected by weave2. the existence of “thisAspect”

related issue: the existence of “thisObject”

Page 89: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

89

static vs. non-static weaves (1)

aspect Count2 { int count = 0; before Point.set, Point.setX, Point.setY { thisAspect.count++; }}

Point p0 = new Point(0,0);Point p1 = new Point(1,1);p0.set(3,3); p1.set(4,4);

aspect Count1 { static int count = 0; static before Point.set, Point.setX, Point.setY { count++; }}

Point p0 = new Point(0,0);Point p1 = new Point(1,1);p0.set(3,3); p1.set(4,4);

static weave affectsall Point objects, always

Count2 count = new Count2();count.addObject(p0);p0.set(3,3);

non-static weave affects justthe Point objects associated with an instance of Count2

Page 90: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

90

static vs. non-static weaves (2)aspect Count1 { static int count = 0; static before Point.set, Point.setX, Point.setY { count++; }}

like a static method, thisweave is executed withoutreference to a particularaspect instance

may be omitted

aspect Count2 { int count = 0; before Point.set, Point.setX, Point.setY { thisAspect.count++; }}

like a non-static method, thisweave is executed withrespect to particularaspect instance(s), thisAspect

thisAspect available in non-static weaves

Page 91: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

91

static vs. non-static (methods)aspect Count1 { static int count = 0; static before Point.set, Point.setX, Point.setY { count++; }}

class Point { int _x = 0; int _y = 0;

void set (int x, int y) { _x = x; _y = y; } void setX (int x) { _x = x; } void setY (int y) { _y = y; } int getX() { return _x; } int getY() { return _y; }}

non-static methods

no particular aspect instance(no thisAspect)buta particular Point object, thisObject

thisObject available in static and non-static weaves of non-static methods

Page 92: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

92

static vs. non-static (specials)

static weave

non-static weave

static method

non-staticmethod

available: thisObject thisAspect thisClassName thisMethdName

available: thisObject thisClassName thisMethodName

available: thisClassName thisMethodName

Page 93: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

93

special methods

• for aspects– void addObject(Object o)– void removeObject(Object o)– Vector getObjects()

• for objects– Vector getAspects()

Page 94: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

94

example: a shared log file

want to log new instances of these classes in one log fileCustomer

Order

Product

Page 95: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

95

static aspect state

Customer

Order

Product

aspect LogNewInstances { static DataOutputStream log = null; static { // initializer try { log = new DataOutputStream( new FileOutputStream(“log”)); } catch (IOException e) {} } static after Customer(*), Order(*), Product(*) { long time = System.currentTimeMillis(); try { log.writeBytes(“New instance at ” + time + “ ” + thisObject.toString() + “\n”); } catch (IOException e) {} }}

globallyshared byCustomer,Order,Product

Page 96: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

96

example: monitoring

DBServer

PrinterServer

WebServer

DocumentServer

ServiceMonitoring

Page 97: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

97

example: monitoringpublic class DBServer { public Result query(Query q) { monitor.anEvent(new SEvent(this)); try { return processQuery(q); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally { monitor.anEvent(new OKEvent(this)); }

} public Status getStatus() { monitor.anEvent(new IEvent(this)); return status;

} ...}

public class PrinterServer { public void print(Path p) { monitor.anEvent(new SEvent(this)); try { printit(p); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public Status getStatus() { monitor.anEvent(new IEvent(this)); return status;

} ...}

public class WebServer { public void post(Data d) { monitor.anEvent(new SEvent(this)); try { postit(d); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public Data get(Path p) { monitor.anEvent(new SEvent(this)); try { return getit(p); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} ...}

public class DocumentServer { public Doc convert(Doc d,Format f) { monitor.anEvent(new SEvent(this)); try { return convertData(d, f); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public void newDocument(Doc d) { monitor.anEvent(new SEvent(this)); try { addDocument(d); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} ...}

Page 98: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

98

example: monitoringpublic class DBServer { public Result query(Query q) { monitor.anEvent(new SEvent(this)); try { return processQuery(q); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally { monitor.anEvent(new OKEvent(this)); }

} public Status getStatus() { monitor.anEvent(new IEvent(this)); return status;

} ...}

public class PrinterServer { public void print(Path p) { monitor.anEvent(new SEvent(this)); try { printit(p); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public Status getStatus() { monitor.anEvent(new IEvent(this)); return status;

} ...}

public class WebServer { public void post(Data d) { monitor.anEvent(new SEvent(this)); try { postit(d); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public Data get(Path p) { monitor.anEvent(new SEvent(this)); try { return getit(p); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} ...}

public class DocumentServer { public Doc convert(Doc d,Format f) { monitor.anEvent(new SEvent(this)); try { return convertData(d, f); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} public void newDocument(Doc d) { monitor.anEvent(new SEvent(this)); try { addDocument(d); } catch (Exception e) { monitor.anEvent(new XEvent(this)); } finally {monitor.anEvent(new OKEvent(this));}

} ...}

monitor.anEvent(new SEvent(this));try { return processQuery(q); }catch (Exception e) { monitor.anEvent(new XEvent(this));} finally { monitor.anEvent(new OKEvent(this));}

Page 99: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

99

aspect as monitor (static state)

aspect ServiceMonitoring { static Vector serversInfo = new Vector(5); static int totalServiceRequests, totalExceptions, totalCompletions;

static before DBServer.query, WebServer.post, WebServer.get, PrinterServer.print, DocumentServer.convert, DocumentServer.newDocument { anEvent(new SEvent(thisObject)); } more befores, afters, catches, finally

static void anEvent(Event e) { update aspect state; sometimes sendCommand } static protected void sendCommand(Server srv, Command c) { srv.anOrder(c); }}

Page 100: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

100

one monitor for all servers (static state)

DBServer

PrinterServer

WebServer

DocumentServer

ServiceMonitoringstatic state

staticweaves

• only one incarnation of the static variables

• weaves statically associated with classes (they affect all objects)

Page 101: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

101

the need for aspect instances

• need different instances of aspect state – e.g. different monitors for different

groups of servers

• need a handle for the aspect state– e.g. remote service monitor

Page 102: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

102

service monitorsaspect ServiceMonitoring { static Vector serversInfo = new Vector(5); static int totalServiceRequests, totalExceptions, totalCompletions;

static before DBServer.query, WebServer.post, WebServer.get, PrinterServer.print, DocumentServer.convert, DocumentServer.newDocument { anEvent(new SEvent(thisObject)); } more befores, afters, catches, finally

static void anEvent(Event e) { update aspect’s state; sometimes sendCommand } static protected void sendCommand(Server srv, Command c) { srv.anOrder(c); }}

Page 103: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

103

monitors for groups of servers

ServiceMonitoring

DBServer

PrinterServer

WebServer

DocumentServer

state

state

non-staticweaves

aServiceMonitor.addObject(aServer)

Page 104: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

104

inheritance of aspects

class MyDocumentServer extends DocumentServer {

protected boolean checkConsistency() { ... }

public Doc convert(Doc d, Format f) { Doc newDoc = super.convert(d, f); if (checkConsistency(newDoc)) return newDoc; else return null; }

}

override

extension

Page 105: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

105

inheritance of aspects

SuperClass

SubClass

Aspect

extends

overriding of methods in sub: • aspect still applies and • doesn’t repeat in calls to super

SuperType applies to all implementationsof designated types

Aspect subclass implementsSuperType

Page 106: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

106

inheritance of aspects

A foo()

B foo()

extends

Aspect1 before A.foo {...}

what code runs in•(new A()).foo() ? Aspect1’s before, A.foo

•(new B()).foo() ? Aspect1’s before, Aspect2’s before, B.foo

• if B.foo calls super.foo() ? same as previous; Aspect1’s before does not repeat

Aspect2 before B.foo {...}

Page 107: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

107

the effective method

{ try { all befores < call to method containing original body > all afters } all catches all finallys}

Page 108: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

108

aspect as monitor (static state)

aspect ServiceMonitoring { static Vector serversInfo = new Vector(5); static int totalServiceRequests, totalExceptions, totalCompletions;

static before DBServer.query, WebServer.post, WebServer.get, PrinterServer.print, DocumentServer.convert, DocumentServer.newDocument { anEvent(new SEvent(thisObject)); } more befores, afters, catches, finally

static void anEvent(Event e) { update aspect state; sometimes sendCommand } static protected void sendCommand(Server srv, Command c) { srv.anOrder(c); }}

Page 109: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

109

inheritance between aspects

aspect VerboseMonitor extends ServiceMonitoring { ObjectOutputStream logStream;

VerboseMonitor() { initialize logStream }

protected void log(Event e) { logStream.writeObject(e); }

public void anEvent(Event e) { System.out.println(e.toString()); log(e); super.anEvent(e); }

}

override

extension

Page 110: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

110

inheritance between aspectsSuperAspect

SubAspect

extends• similar to inheritance between classes:– subaspect inherits methods, fields

and weaves of superaspect– subaspect can extend superaspect

with new methods, fields and weaves– subaspect can override methods and

fields of superaspect (for now)

Page 111: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

111

aspects that localize shared state

A

B

C

O

A

B

C

Aspect

used in• multi-class protocols with state

– authentication– monitoring– object management– ...

• encapsulation of state relating to groups of objects

Page 112: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

112

aspects that localize shared state

• state needs to be encapsulated• an object / a class would do, but• interactions that affect the state of

such object are well localized

• aspect contains that state and the weaves for interaction

Page 113: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

113

outline

• using aspects to localize :– common implementations– interaction (protocols)– shared state

• specialized aspect libraries– cross-cutting abstractions– code-intensive, repetitive actions

(goal of all libraries)

Page 114: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

114

the cross-cutting nature of concurrency control

Problem: a square and a circle are manipulated by several concurrent threads. They can both change color. However, they can’t both be red at the same time; a changeColor(red) request on one of them must wait if the other is currently red.

Not OKOK

Page 115: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

115

cross-cutting is unavoidable

the cross-cutting nature of concurrency control

class Square extends Shape { Pos pos; int size; Color color; fields for coordination

public void changeColor(Color c){ some coordination code here color = c; some coordination code here } …}

class Circle extends Shape { Pos pos; int r; Color color; fields for coordination

public void changeColor(Color c){ some coordination code here color = c; some coordination code here } …}

code may be more or less encapsulated, but

Page 116: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

116

aspect NoSimultaneousRed { Shape redShape = null; // holds the reference to // the red shape or null

before void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color == Color.red) { synchronized (thisAspect) { while (!(redShape == null || redShape == thisObject)) { try { wait(); } catch (InterruptedException e) {} } redShape = thisObject; } }

} after void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color != Color.red) { synchronized (thisAspect) { if (thisObject == redShape) // coming out of red redShape = null; notifyAll(); } }

}}

using an aspectaspect NoSimultaneousRed { Shape redShape = null; // holds the reference to // the red shape or null

before void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color == Color.red) { synchronized (thisAspect) { while (!(redShape == null || redShape == thisObject)) { try { wait(); } catch (InterruptedException e) {} } redShape = thisObject; } }

} after void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color != Color.red) { synchronized (thisAspect) { if (thisObject == redShape) // coming out of red redShape = null; notifyAll(); } }

}}

Page 117: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

117

using an aspectaspect NoSimultaneousBlue { Shape blueShape = null; // holds the reference to // the blue shape or null

before void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color == Color.blue) { synchronized (thisAspect) { while (!(blueShape == null || blueShape == thisObject)) { try { wait(); } catch (InterruptedException e) {} } blueShape = thisObject; } }

} after void Square.changeColor(Color color), void Circle.changeColor(Color color) { if (color != Color.blue) { synchronized (thisAspect) { if (thisObject == blueShape) // coming out of blue blueShape = null; notifyAll(); } }

}}

can pull outcommoncodeinto asuper

Page 118: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

118

using coolibaspect NoSimultaneousRed extends Coordinator { Shape redShape = null; before void Square.changeColor(String color), void Circle.changeColor(String color) { if (color == Color.red) guardedEntry(thisMethodID, new Condition() { boolean checkit() { return (redShape == null || redShape == thisObject);}}, new CoordinationAction() { void doit() { redShape = thisObject; } });

} after void Square.changeColor(String color), void Circle.changeColor(String color) { if (color != Color.red) guardedExit(thisMethodID, new CoordinationAction() { void doit() {if (thisObject==redShape) redShape = null;}});

}}

aspect NoSimultaneousRed extends Coordinator { Shape redShape = null; before void Square.changeColor(String color), void Circle.changeColor(String color) { if (color == Color.red) guardedEntry(thisMethodID, new Condition() { boolean checkit() { return (redShape == null || redShape == thisObject);}}, new CoordinationAction() { void doit() { redShape = thisObject; } });

} after void Square.changeColor(String color), void Circle.changeColor(String color) { if (color != Color.red) guardedExit(thisMethodID, new CoordinationAction() { void doit() {if (thisObject==redShape) redShape = null;}});

}}

Page 119: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

119

coolib

• avoid writing ad-hoc coordination code in the classes: use coordination aspects

• provide high-level constructs for programming coordination

Page 120: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

120

coolib

• mutual exclusion• coordination state• conditional suspension/notification• coordination actions

Page 121: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

121

coolib

Coordinator

guardedEntry(String methName, boolean condition, CoordinationAction act)guardedExit(String methName, CoordinationAction act)addSelfex(String methName)addMutex(String[] methNames)

some other variants ofguardedEntry and guardedExit

CoordinationAction

doit()

Condition

checkit()

included in distribution of AspectJ

Page 122: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

122

summary• aspects capture design abstractions

that involve several classes• many different flavors of aspects

– common implementations– protocols– state plus protocol

• aspects build on existing practices and techniques for OO– instantiation, inheritance– libraries for programming aspects

(e.g. coolib)

Page 123: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Part VStyle Issues

Page 124: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

124

outline

• when to use aspects– what existing knowledge tells us

• coding style issues– aspect/class interface– recursion

Page 125: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

125

good designs

• capture “the story” well• may lead to good

implementations, measured by– code size– tangling– coupling– etc.

learned through experience,

influenced by taste and style

Page 126: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

126

3 examples

• pull out access tracing • pull out error handling• pull out X and Y

Page 127: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

127

a good aspect (access tracing)class Point { ... void set (int x, int y) {...} void setX (int x) { ... } void setY (int y) { ... } int getX() { ... } int getY() { ... }}

aspect ShowAccesses { static before Point.set, Point.setX, Point.setY, Line.set, Line.setX1, Line.setY1, Line.setX2, Line.setY2 { System.out.println(“W”); }}

“access tracing” is a good abstraction on its own

class Line { ... void set(int x1,int y1, int x2,int y2) {...} void setX1 (Point p) {...} void setY1 (Point p) {...} void setX2 (Point p) {...} void setY2 (Point p) {...}}

Page 128: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

128

a good aspect (access tracing)class Point { int _x = 0; int _y = 0;

void set (int x, int y) { System.out.println(“W”); _x = x; _y = y;

} void setX (int x) { System.out.println(“W”); _x = x;

} void setY (int y) { System.out.println(“W”); _y = y;

} int getX() { return _x;

} int getY() { return _y;

}}

alternative implementation:

• more tangled

• redundant information

• commonality is lost

• consistent change is harder

• harder to unplug

harder to maintain

Page 129: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

129

a good aspect (errors)class DocumentServer { Doc convert(Doc d,Format f){ search locally and remotely } DocID lookupDoc (…) { search locally and remotely } void storeDoc (…) { store locally, notify remotely } void scanDoc (…) { get document from scanner }}

aspect DocumentServerErrors { static catch (RemoteException e) DocumentServer.lookupDoc, DocumentServer.storeDoc { pop up message offering to change the default server } static catch (DeviceError e) DocumentServer.convert, DocumentServer.scanDoc { pop up message offering to call the key operator }}

“how to deal with errors in the document server” is a good abstraction on its own

Page 130: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

130

a good aspect (errors)class DocumentServer { Doc convert(Doc d,Format f){ try { search locally and remotely } catch (DeviceError e) { pop up message offering to call the key operator } } DocID lookupDoc (…) { try { search locally and remotely } catch (RemoteException e) { pop up message offering to change the default server } } void storeDoc (…) { try { store locally, notify remotely } catch (RemoteException e) { pop up message offering to change the default server } } ...

alternative implementation:

• more tangled

• redundant information

• commonality is lost

• consistent change is harder

• harder to unplug

harder to maintain

even single-class aspects can help, if they separate out some reasonable design concern

Page 131: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

131

two questionable aspects

class Point {}

aspect XPart { static new Point._x = 0; static new int Point.getX() { return _x; } static new void Point.setX(int x) { _x = x; }}aspect YPart { static new int Point._y = 0; static new int Point.getY() { return _y; } static new void Point.setY(int y) { _y = y; }}

points havethese 2 parts,butdoes it reallymake sense toseparate them?

where does set go? other methods that need x and y?

do these 2 aspects improve the code?

Page 132: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

132

two questionable aspects

class Point { int _x = 0; int _y = 0; void setX (int x) { _x = x; } void setY (int y) { _y = y; } int getX() { return x; } int getY() { return y; } void set (int x, int y) { _x = x; _y = y; }}

the Point class is a goodimplementation of thepoint abstraction:

• no redundant information• no lost commonalties• no tangling• no difference in size• plug in/out: what’s a point without the X part?

not really

do these 2 aspects improve the code?

Page 133: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

133

when to use aspects

• is there a concern that:– cross-cuts the structure of several

classes or methods– is beneficial to separate out

Page 134: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

134

… cross-cutting

• a design concern that involves several classes or methods

• implemented without AOP would lead to distant places in the code that– do the same thing

• (i.e. println(“W”), logging)• try grep to find these [Griswald]

– do a coordinated single thing• (i.e. observer pattern, synchronization)• harder to find these

Page 135: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

135

… beneficial to separate out

does it improve the code in real ways?– separation of concerns

• think about service without logging

– clarifies interactions, reduces tangling• all the log.writeBytes are really the same• checking that the “other object” isn’t red

– easier to modify / extend• change “W” to “a variable was set”• aspect frameworks

– plug and play• can turn off aspect easily• debugging aspects unplugged but not deleted

Page 136: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

136

benefits of using AOP

• good modularity, even in the presence of cross-cutting concerns– less tangled code, more natural code,

smaller code– easier maintenance and evolution

• easier to reason about, debug, change

– more reusable• plug and play

Page 137: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

137

one-to-one association trick

obj

aspSomeAspect asp = new SomeAspect();SomeClass obj = new SomeClass();asp.addObject(obj);

aspect SomeAspect { static after SomeClass(*) { SomeAspect asp = new SomeAspect(); asp.addObject(thisObject); } ...}

SomeClass obj = new SomeClass();// aspect instance is associated with obj

make aspect know about class more than the other way

Page 138: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

Part VIReferences, Related Work

Page 139: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

139

AOP and AspectJ on the web

• http://www.parc.xerox.com/aop

• http://www.parc.xerox.com/aop/aspectj

Page 140: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

140

workshops

• ECOOP’97– http://wwwtrese.cs.utwente.nl/aop-ecoop97

• ICSE’98– http://www.parc.xerox.com/aop/icse98

• ECOOP’98– http://wwwtrese.cs.utwente.nl/aop-ecoop98

Page 141: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

141

AOP publications

• in proceedings of ECOOP’97• tech reports from PARC

– http://www.parc.xerox.com/aop

• workshop papers– see workshop pages

Page 142: Aspect-Oriented Programming w/AspectJ™ Cristina Lopes, Gregor Kiczales Xerox PARC © Copyright 1998, Xerox Corporation. All Rights Reserved

142

work we know best

• subject-oriented programming @ IBM

– [Ossher, Harrison]

• adaptive programming @ Northeastern U

– [Lieberherr]

• composition filters @ U Twente

– [Aksit]

• assessment of SE techniques @ UBC– [Murphy]

• information transparency @ UCSD– [Griswald]