Top Banner
Aspect-Oriented Programming and Design For Java and AspectJ Dean Wampler Object Mentor, Inc. [email protected] 1 Friday, September 7, 2007
89
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 2: Aspect Oriented Programming and Design

public class Account { public Money getBalance() {...} public void credit(Money m) {...} public void debit(Money m) {...} ... }

2Friday, September 7, 2007

Page 3: Aspect Oriented Programming and Design

public void credit(Money m) { balance += m;}

For example...

3Friday, September 7, 2007

Page 4: Aspect Oriented Programming and Design

Cleanand

Simple4Friday, September 7, 2007

Page 5: Aspect Oriented Programming and Design

However,

Real applications need:

public class BankAccount {

public Money getBalance(){...}

public void credit(Money m) {...}

public void debit(Money m) {...}

...

}

Transactions

Persistence

Security

5Friday, September 7, 2007

Page 6: Aspect Oriented Programming and Design

public void credit(Money m) { if (unauthorized()) throw new ...(); Money saveBalance = balance; try { beginTransaction(); balance += m; persistBalance(balance); } ...

Back to our example...

6Friday, September 7, 2007

Page 7: Aspect Oriented Programming and Design

... } catch (...) { balance = savedBalance; } finally { endTransaction(); }}

7Friday, September 7, 2007

Page 8: Aspect Oriented Programming and Design

What’s wrong??

8Friday, September 7, 2007

Page 9: Aspect Oriented Programming and Design

We’re mixing multiple domains,

Transactions

Persistence

Security

with fine-grained intersections.

“Problem Domain”

“tangled” code

“scattered” logic

9Friday, September 7, 2007

Page 10: Aspect Oriented Programming and Design

Aspects restore modularity byencapsulating the intersections.

Transactions

Persistence

Security

TransactionAspect

PersistenceAspect

SecurityAspect

10Friday, September 7, 2007

Page 11: Aspect Oriented Programming and Design

Obvious uses:

PersistenceTransactions

SecurityLogging

others...

11Friday, September 7, 2007

Page 12: Aspect Oriented Programming and Design

public void credit(Money m) { balance += m;}

Back to our example...

Back to what we want...

12Friday, September 7, 2007

Page 13: Aspect Oriented Programming and Design

public aspect PersistentAccount{ pointcut newBalance ( Account a, Money newBal): set (Money Account.balance) && args (newBal) && this (a); ...

Back to our example...class-like declaration

named set of “join points”

bind variables

any time “balance” is setremember new value

remember “this”

13Friday, September 7, 2007

Page 14: Aspect Oriented Programming and Design

... after ( Account a, Money newBal) : newBalance(a, newBal) { persist(a, newBal);}

Back to our example...

“after advice” same arguments

same pointcut

body of the advice

14Friday, September 7, 2007

Page 15: Aspect Oriented Programming and Design

Types of advice

beforeafter returningafter throwing

afteraround

15Friday, September 7, 2007

Page 16: Aspect Oriented Programming and Design

Other terms

• Join point

• Pointcut

• Advice

• Cross-cutting concern

• Introduction (a.k.a. Inter-type declaration)

• Aspect

16Friday, September 7, 2007

Page 17: Aspect Oriented Programming and Design

Pure Java AOPSpring AOPJBoss AOP

17Friday, September 7, 2007

Page 18: Aspect Oriented Programming and Design

Spring AOP@AspectJ Support

18Friday, September 7, 2007

Page 19: Aspect Oriented Programming and Design

@Aspect class PersistentAccount { @Pointcut (“execution(* Account.*(..))”) private void newBalance() {}

@After(“newBalance()”) private void persistChange() {...}}

19Friday, September 7, 2007

Page 20: Aspect Oriented Programming and Design

<aop:aspectj-autoproxy/>...<bean id=”persistantAccount” class=”...PersistentAccount”> <!-- properties of bean --></bean>

auto-configure @Aspects

The usual Spring bean stuff...

20Friday, September 7, 2007

Page 21: Aspect Oriented Programming and Design

<aop:config> <aop:advisor pointcut="....newBalance()" advice-ref="tx-advice"/> </aop:config>

<tx:advice id="tx-advice"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>

Wire another advice using XML

21Friday, September 7, 2007

Page 22: Aspect Oriented Programming and Design

Spring’sDependency Injection

can also wire “POJO” aspects

22Friday, September 7, 2007

Page 23: Aspect Oriented Programming and Design

Recommendation:Use Spring to introduce AOP into your environment.

23Friday, September 7, 2007

Page 24: Aspect Oriented Programming and Design

JBoss AOP works in similar ways.

24Friday, September 7, 2007

Page 25: Aspect Oriented Programming and Design

Aspect-Oriented Design(Starting in the early years)

25Friday, September 7, 2007

Page 26: Aspect Oriented Programming and Design

“Classes should be oblivious to aspects.”

26Friday, September 7, 2007

Page 27: Aspect Oriented Programming and Design

However, this leads to...

27Friday, September 7, 2007

Page 28: Aspect Oriented Programming and Design

Persistence Aspect

PCD: set (* *.name)

Account

name

Account

first_namelast_name

Version 1 Version 2

???X

28Friday, September 7, 2007

Page 29: Aspect Oriented Programming and Design

Aspects make initial version easier,

But subsequent versions harder!

29Friday, September 7, 2007

Page 30: Aspect Oriented Programming and Design

AOP-Evolution

Paradox!

30Friday, September 7, 2007

Page 31: Aspect Oriented Programming and Design

Obliviousness ...

... is like that.

31Friday, September 7, 2007

Page 32: Aspect Oriented Programming and Design

We forgot established

OOD Principles.

32Friday, September 7, 2007

Page 33: Aspect Oriented Programming and Design

Principles of OOD

11

33Friday, September 7, 2007

Page 34: Aspect Oriented Programming and Design

Single Responsibility Principle

A class should have only one reason to change.

#1

34Friday, September 7, 2007

Page 35: Aspect Oriented Programming and Design

Open-Closed Principle

A module should be open for extension, but closed

for modification.

#2

35Friday, September 7, 2007

Page 36: Aspect Oriented Programming and Design

An Example...

36Friday, September 7, 2007

Page 37: Aspect Oriented Programming and Design

public interface Shape { public double getArea(); public void draw(); }

37Friday, September 7, 2007

Page 38: Aspect Oriented Programming and Design

public abstract class Polygon implements Shape { public Point getVertex(int index)

{...} public void draw() {...} public String toString() {...} }

38Friday, September 7, 2007

Page 39: Aspect Oriented Programming and Design

public class Square extends Polygon { public double getArea() {...} }

public class Rectangle extends Polygon { public double getArea() {...}}

39Friday, September 7, 2007

Page 40: Aspect Oriented Programming and Design

Square is a Rectangle?

Isn’t it?

is a

40Friday, September 7, 2007

Page 41: Aspect Oriented Programming and Design

public interface Shape { public double getArea(); public void draw(); }

An Aspect Refactoring...

41Friday, September 7, 2007

Page 42: Aspect Oriented Programming and Design

public abstract class Polygon implements Shape { public Point getVertex(int index)

{...} public void draw() {...} public String toString() {...} }

42Friday, September 7, 2007

Page 43: Aspect Oriented Programming and Design

package shapes.tostring;public aspect PolygonToString { public String Polygon.toString() {...} }

43Friday, September 7, 2007

Page 44: Aspect Oriented Programming and Design

package drawing;public interface Drawable { void draw(); }

44Friday, September 7, 2007

Page 45: Aspect Oriented Programming and Design

package shapes.drawing;import drawing.Drawable;

abstract aspect DrawableShape { declare parents:

Shape implements Drawable;

public void Shape.draw() { String cmd = makeDrawCmd();getGraphics().sendCmd(cmd);

}abstract String makeDrawCmd();

} 45Friday, September 7, 2007

Page 46: Aspect Oriented Programming and Design

Liskov Substitution Principle

Subtypes must be substitutable for their

base types.

#3

46Friday, September 7, 2007

Page 47: Aspect Oriented Programming and Design

Square is a Rectangle?is a

What do the unit tests say?

47Friday, September 7, 2007

Page 48: Aspect Oriented Programming and Design

public RectangleDrawTest extends ... {

public void testDraw {Shape[] shapes = new Shapes[] {new Rectangle(...),new Square(...)};

for (Shape s: shapes)s.draw(); // just works...

}}

48Friday, September 7, 2007

Page 49: Aspect Oriented Programming and Design

Apparently, it is!!

Square is a Rectangle?is a

(at least in this context...)

49Friday, September 7, 2007

Page 50: Aspect Oriented Programming and Design

Mutability...

50Friday, September 7, 2007

Page 51: Aspect Oriented Programming and Design

public abstract class Polygon implements Shape { public Point getVertex(int index)

{...} List<Point> getVertices() {...}}

Need to Change Polygon:

Occasionally need to break OCP...

Package private!

51Friday, September 7, 2007

Page 52: Aspect Oriented Programming and Design

package shapes; // same packageimport ...;

aspect MutablePolygon {

public void Polygon.setHeight(int i) { List<Point> list = getVertices(); // Change appropriate points... } public void Polygon.setWidth(int i) {...} }

52Friday, September 7, 2007

Page 53: Aspect Oriented Programming and Design

Square is a Rectangle?is a

53Friday, September 7, 2007

Page 54: Aspect Oriented Programming and Design

public MutableRectangleTest ... {public void testSetWidth{Point p00, p20, p25, p05 = ...;Rectangle rect = new Rectangle(p00,p20,p25,p05);

(0,0)

(0,5) (2,5)

(2,0)

54Friday, September 7, 2007

Page 55: Aspect Oriented Programming and Design

public MutableRectangleTest ... {public void testSetWidth{Point p00, p20, p25, p05 = ...;Rectangle r = new Rectangle(p00,p20,p25,p05);assertEquals(2, r.getWidth());assertEquals(5, r.getHeight());

}}

r.setWidth(3);assertEquals(3, r.getWidth());assertEquals(5, r.getHeight());

55Friday, September 7, 2007

Page 56: Aspect Oriented Programming and Design

Square is a Rectangle?

Prove it! (or not...)

is a

56Friday, September 7, 2007

Page 57: Aspect Oriented Programming and Design

...Rectangle r = new Square(p00,p50,p55,p05);assertEquals(5, r.getWidth());assertEquals(5, r.getHeight());

r.setWidth(3);

assertEquals(3, r.getWidth());assertEquals(5, r.getHeight());

What if I Use a Square?

This won’t pass!

57Friday, September 7, 2007

Page 58: Aspect Oriented Programming and Design

Square is a Rectangle?

Not inthis context!!

is a

58Friday, September 7, 2007

Page 59: Aspect Oriented Programming and Design

LSP

Context Dependent!

Is

59Friday, September 7, 2007

Page 60: Aspect Oriented Programming and Design

LSP Is the Basis for

Design by Contract

60Friday, September 7, 2007

Page 61: Aspect Oriented Programming and Design

Shameless Plug...61Friday, September 7, 2007

Page 62: Aspect Oriented Programming and Design

@Contractpublic abstract class Polygon implements Shape { @Pre(“index>=0”)@Post(“$return != null”) public Point getVertex(int index){...}

}

Contract4J: DbC for Javaannotation-based

62Friday, September 7, 2007

Page 63: Aspect Oriented Programming and Design

Dependency Inversion Principle

Abstractions should not depend upon details.

Details should depend upon abstractions.

#5

63Friday, September 7, 2007

Page 64: Aspect Oriented Programming and Design

Client

Service

Client Service

Service

64Friday, September 7, 2007

Page 65: Aspect Oriented Programming and Design

Client «aspec t»ClientService

Service

Client «aspec t»ClientService

Service

Client Service

Service

65Friday, September 7, 2007

Page 66: Aspect Oriented Programming and Design

New AOD Principles

66Friday, September 7, 2007

Page 67: Aspect Oriented Programming and Design

package shapes.tostring;public aspect PolygonToString { public String Polygon.toString() {...} } Do introductions violate OCP??

No

67Friday, September 7, 2007

Page 68: Aspect Oriented Programming and Design

Open-Closed Principle: UpdatedA module should be open for

extension, but closed for source and contract modification.

68Friday, September 7, 2007

Page 69: Aspect Oriented Programming and Design

public aspect Tracer { before(): call(* Polygon.*(..)) { log(thisJoinPointStaticPart); } }

public class LoggedPolygonDraws { public void draw() { log(“Polygon.draw”); super.draw(); } }

Similar!

69Friday, September 7, 2007

Page 70: Aspect Oriented Programming and Design

Liskov Substitution Principle: Updated

Subtypes and aspects + base types must be substitutable for

their base types.

70Friday, September 7, 2007

Page 71: Aspect Oriented Programming and Design

public aspect PolygonMunger { before(Polygon p): target(p) && call(* Polygon.draw(..)) { p.addPoint(new Point(/*...*/)); } }

Does this look safe??

71Friday, September 7, 2007

Page 72: Aspect Oriented Programming and Design

Advice Substitution Principle

Advice must obey the contract of the advised join point.

72Friday, September 7, 2007

Page 73: Aspect Oriented Programming and Design

public aspect CirclingPolygons { public double Polygon.getRadius() {...} public Point Polygon.getCenter() {...}}

Huh??

73Friday, September 7, 2007

Page 74: Aspect Oriented Programming and Design

Introduction Substitution Principle

Introductions must obey the contract of the module.

74Friday, September 7, 2007

Page 75: Aspect Oriented Programming and Design

public aspect PersistentAccount { after (Account a): target(a) && call(* Account.setName()) { persistName(a.getName()); }}

What happens when “name” is refactored to “firstName” and “lastName”??

75Friday, September 7, 2007

Page 76: Aspect Oriented Programming and Design

Pointcut Inversion Principle

Pointcuts should not depend upon concrete details.

Pointcuts should depend upon abstractions.

76Friday, September 7, 2007

Page 77: Aspect Oriented Programming and Design

The Future of AOP

77Friday, September 7, 2007

Page 78: Aspect Oriented Programming and Design

• Much hyped in the 90s

• All or nothing proposition

• ... due to internal dependencies

Components and Frameworks

Can aspects reduce the coupling and make them more reusable?

78Friday, September 7, 2007

Page 79: Aspect Oriented Programming and Design

Client «aspec t»ClientService

Service

Client «aspec t»ClientService

Service

79Friday, September 7, 2007

Page 80: Aspect Oriented Programming and Design

• High-level defines policy

• Low-level defines details

Improved Architectures

Better separation using aspects?

80Friday, September 7, 2007

Page 81: Aspect Oriented Programming and Design

• Domain-Specific Languages for the high-level

• Connect to low-level details with aspects

Improved Architectures

81Friday, September 7, 2007

Page 82: Aspect Oriented Programming and Design

public class PersistenceDSL { public PersistenceDSL() { after() .calling(methodsIn( interface(StateChange.class))) .then(persistChange()); }}

(Fanciful, made-up example...)

82Friday, September 7, 2007

Page 83: Aspect Oriented Programming and Design

Conclusions

83Friday, September 7, 2007

Page 84: Aspect Oriented Programming and Design

Real applications...

mix multiple domains...

causing tangled code.

84Friday, September 7, 2007

Page 85: Aspect Oriented Programming and Design

Objects alone don’t prevent this tangling.

85Friday, September 7, 2007

Page 86: Aspect Oriented Programming and Design

Aspects modularize the intersection

of the domains.intersection

86Friday, September 7, 2007

Page 87: Aspect Oriented Programming and Design

Obvious uses:

PersistenceTransactions

SecurityLogging

others...

87Friday, September 7, 2007

Page 88: Aspect Oriented Programming and Design

The future?

Better architectures(Domain-specific languages)

Better components and frameworks

88Friday, September 7, 2007