Aspect Oriented Programming and Design
-
Upload
manikanda-kumar -
Category
Technology
-
view
4.441 -
download
5
Transcript of Aspect Oriented Programming and Design
Aspect-OrientedProgramming and Design
For Java and AspectJ
Dean WamplerObject Mentor, Inc.
1Friday, September 7, 2007
public class Account { public Money getBalance() {...} public void credit(Money m) {...} public void debit(Money m) {...} ... }
2Friday, September 7, 2007
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
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
... } catch (...) { balance = savedBalance; } finally { endTransaction(); }}
7Friday, September 7, 2007
We’re mixing multiple domains,
Transactions
Persistence
Security
with fine-grained intersections.
“Problem Domain”
“tangled” code
“scattered” logic
9Friday, September 7, 2007
Aspects restore modularity byencapsulating the intersections.
Transactions
Persistence
Security
TransactionAspect
PersistenceAspect
SecurityAspect
10Friday, September 7, 2007
public void credit(Money m) { balance += m;}
Back to our example...
Back to what we want...
12Friday, September 7, 2007
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
... 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
Other terms
• Join point
• Pointcut
• Advice
• Cross-cutting concern
• Introduction (a.k.a. Inter-type declaration)
• Aspect
16Friday, September 7, 2007
@Aspect class PersistentAccount { @Pointcut (“execution(* Account.*(..))”) private void newBalance() {}
@After(“newBalance()”) private void persistChange() {...}}
19Friday, September 7, 2007
<aop:aspectj-autoproxy/>...<bean id=”persistantAccount” class=”...PersistentAccount”> <!-- properties of bean --></bean>
auto-configure @Aspects
The usual Spring bean stuff...
20Friday, September 7, 2007
<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
Persistence Aspect
PCD: set (* *.name)
Account
name
Account
first_namelast_name
Version 1 Version 2
???X
28Friday, September 7, 2007
Single Responsibility Principle
A class should have only one reason to change.
#1
34Friday, September 7, 2007
Open-Closed Principle
A module should be open for extension, but closed
for modification.
#2
35Friday, September 7, 2007
public abstract class Polygon implements Shape { public Point getVertex(int index)
{...} public void draw() {...} public String toString() {...} }
38Friday, September 7, 2007
public class Square extends Polygon { public double getArea() {...} }
public class Rectangle extends Polygon { public double getArea() {...}}
39Friday, September 7, 2007
public interface Shape { public double getArea(); public void draw(); }
An Aspect Refactoring...
41Friday, September 7, 2007
public abstract class Polygon implements Shape { public Point getVertex(int index)
{...} public void draw() {...} public String toString() {...} }
42Friday, September 7, 2007
package shapes.tostring;public aspect PolygonToString { public String Polygon.toString() {...} }
43Friday, September 7, 2007
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
Liskov Substitution Principle
Subtypes must be substitutable for their
base types.
#3
46Friday, September 7, 2007
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
Apparently, it is!!
Square is a Rectangle?is a
(at least in this context...)
49Friday, September 7, 2007
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
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
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
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
...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
@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
Dependency Inversion Principle
Abstractions should not depend upon details.
Details should depend upon abstractions.
#5
63Friday, September 7, 2007
Client «aspec t»ClientService
Service
Client «aspec t»ClientService
Service
Client Service
Service
65Friday, September 7, 2007
package shapes.tostring;public aspect PolygonToString { public String Polygon.toString() {...} } Do introductions violate OCP??
No
67Friday, September 7, 2007
Open-Closed Principle: UpdatedA module should be open for
extension, but closed for source and contract modification.
68Friday, September 7, 2007
public aspect Tracer { before(): call(* Polygon.*(..)) { log(thisJoinPointStaticPart); } }
public class LoggedPolygonDraws { public void draw() { log(“Polygon.draw”); super.draw(); } }
Similar!
69Friday, September 7, 2007
Liskov Substitution Principle: Updated
Subtypes and aspects + base types must be substitutable for
their base types.
70Friday, September 7, 2007
public aspect PolygonMunger { before(Polygon p): target(p) && call(* Polygon.draw(..)) { p.addPoint(new Point(/*...*/)); } }
Does this look safe??
71Friday, September 7, 2007
Advice Substitution Principle
Advice must obey the contract of the advised join point.
72Friday, September 7, 2007
public aspect CirclingPolygons { public double Polygon.getRadius() {...} public Point Polygon.getCenter() {...}}
Huh??
73Friday, September 7, 2007
Introduction Substitution Principle
Introductions must obey the contract of the module.
74Friday, September 7, 2007
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
Pointcut Inversion Principle
Pointcuts should not depend upon concrete details.
Pointcuts should depend upon abstractions.
76Friday, September 7, 2007
• 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
Client «aspec t»ClientService
Service
Client «aspec t»ClientService
Service
79Friday, September 7, 2007
• High-level defines policy
• Low-level defines details
Improved Architectures
Better separation using aspects?
80Friday, September 7, 2007
• Domain-Specific Languages for the high-level
• Connect to low-level details with aspects
Improved Architectures
81Friday, September 7, 2007
public class PersistenceDSL { public PersistenceDSL() { after() .calling(methodsIn( interface(StateChange.class))) .then(persistChange()); }}
(Fanciful, made-up example...)
82Friday, September 7, 2007
The future?
Better architectures(Domain-specific languages)
Better components and frameworks
88Friday, September 7, 2007
Thank You!
• http://objectmentor.com
• http://aspectprogramming.com
• http://contract4j.org
• http://aquarium.rubyforge.org
89Friday, September 7, 2007