Your SlideShare is downloading. ×
0
Aspect-Oriented
            Programming and Design
                               For Java and AspectJ

                  ...
public class Account {
        public Money getBalance()
        {...}
        public void credit(Money m)
        {...}
 ...
For example...
      public void credit(Money m) {
        balance += m;
      }




Friday, September 7, 2007            ...
Clean
                              and




                            Simple
Friday, September 7, 2007            4
However,
                    Real applications need:

                                            Transactions
      publi...
Back to our example...
      public void credit(Money m) {
        if (unauthorized())
          throw new ...();
        ...
...
             } catch (...) {
               balance = savedBalance;
             } finally {
               endTransac...
What’s wrong??


Friday, September 7, 2007          8
We’re mixing multiple domains,
    with fine-grained intersections.
                            “tangled” code
            ...
Aspects restore modularity by
       encapsulating the intersections.
                            Transaction
            ...
Obvious uses:
                              Persistence
                              Transactions
                       ...
Back to our example...
      public void credit(Money m) {
        balance += m;
      }
                      Back to wha...
Back to our example...
                                class-like declaration
  public aspect PersistentAccount{
    point...
Back to our example...
                 “after advice”
      ...                              same arguments
        after...
Types of advice
                                  before
                              after returning
                   ...
Other terms
                • Join point
                • Pointcut
                • Advice
                • Cross-cutti...
Pure Java AOP
                                Spring AOP
                                JBoss AOP




Friday, September 7...
Spring AOP
                             @AspectJ Support




Friday, September 7, 2007                       18
@Aspect
      class PersistentAccount {
       @Pointcut
       (“execution(* Account.*(..))”)
       private void newBala...
auto-configure @Aspects
      <aop:aspectj-autoproxy/>
      ...
      <bean id=”persistantAccount”
       class=”...Persis...
<aop:config>          Wire another advice
                                using XML
       <aop:advisor
        pointcut=q...
Spring’s
                       Dependency Injection
                          can also wire
                        “POJO...
Recommendation:
                Use Spring to introduce AOP into your environment.




Friday, September 7, 2007          ...
JBoss AOP works in
                          similar ways.


Friday, September 7, 2007                   24
Aspect-Oriented Design
                            (Starting in the early years)




Friday, September 7, 2007            ...
“Classes should be
                            oblivious to aspects.”


Friday, September 7, 2007                         ...
However, this leads to...



Friday, September 7, 2007                  27
Persistence Aspect

                                    PCD: set (* *.name)


                                            ...
Aspects make initial version easier,


                   But subsequent versions harder!




Friday, September 7, 2007   ...
!
                       AOP-Evolution
                                        x
                                       o
...
Obliviousness ...
                    ... is like that.

Friday, September 7, 2007               31
We forgot
                            established
                              OOD
                            Principles...
11
                            Principles of
                               OOD
Friday, September 7, 2007                 ...
#1

              Single Responsibility
                    Principle
                  A class should have only
         ...
#2

                            Open-Closed
                             Principle
               A module should be open
...
An Example...




Friday, September 7, 2007                   36
public interface Shape {
                     public double getArea();
                     public void draw();
          ...
public abstract class Polygon
   implements Shape {
    public Point getVertex(int index)
     {...}
    public void draw(...
public class Square
     extends Polygon {
        public double getArea() {...}
      }

    public class Rectangle
     ...
Square is a Rectangle?

                            Isn’t it?

Friday, September 7, 2007                   40
An Aspect Refactoring...

                    public interface Shape {
                     public double getArea();
     ...
public abstract class Polygon
   implements Shape {
    public Point getVertex(int index)
     {...}
    public void draw(...
package shapes.tostring;
  public aspect PolygonToString {
    public String Polygon.toString()
     {...}
  }




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




Friday, Septem...
package shapes.drawing;
 import drawing.Drawable;
 abstract aspect DrawableShape {
   declare parents:
    Shape implement...
#3

                   Liskov Substitution
                        Principle
                         Subtypes must be
   ...
Square is a Rectangle?

          What do the unit tests say?


Friday, September 7, 2007                   47
public RectangleDrawTest                       {
                                   extends ...

      public void testDra...
Square is a Rectangle?
                            Apparently, it is!!
                            (at least in this conte...
Mutability...



Friday, September 7, 2007                   50
Need to Change Polygon:
  public abstract class Polygon
   implements Shape {
    public Point getVertex(int index)
     {...
package shapes; // same package
 import ...;
 aspect MutablePolygon {
  public void
   Polygon.setHeight(int i) {
     Lis...
Square is a Rectangle?




Friday, September 7, 2007                   53
public MutableRectangleTest ... {
  public void testSetWidth{
   Point p00, p20, p25, p05 = ...;
   Rectangle rect =
    n...
public MutableRectangleTest ... {
  public void testSetWidth{
   Point p00, p20, p25, p05 = ...;
   Rectangle r = new Rect...
Square is a Rectangle?

                            Prove it! (or not...)

Friday, September 7, 2007                      ...
What if I Use a Square?
        ...
        Rectangle r = new Square
         (p00,p50,p55,p05);
        assertEquals(5, r...
Square is a Rectangle?
                                Not in
                            this context!!

Friday, Septembe...
LSP
                                    Is
                            Context Dependent!

Friday, September 7, 2007      ...
LSP Is the Basis for

                            Design by Contract


Friday, September 7, 2007                          60
Shameless Plug...
Friday, September 7, 2007                       61
Contract4J: DbC for Java
                            annotation-based
  @Contract
  public abstract class Polygon
   imple...
#5

                       Dependency
                    Inversion Principle
          Abstractions should not depend upo...
Client            Service
                                Client




                      Service            Service




...
Service
                                  Client




                                            Service




             ...
New AOD Principles



Friday, September 7, 2007                 66
package shapes.tostring;
  public aspect PolygonToString {
    public String Polygon.toString()
     {...}
  }            ...
Open-Closed
                     Principle: Updated
                  A module should be open for
                extensio...
public aspect Tracer {
    before(): call(* Polygon.*(..)) {
      log(thisJoinPointStaticPart);
    }
                   ...
Liskov Substitution
                   Principle: Updated
                 Subtypes and aspects + base
                 ty...
public aspect PolygonMunger {
   before(Polygon p): target(p) &&
     call(* Polygon.draw(..)) {
      p.addPoint(new Poin...
Advice Substitution
                      Principle
                 Advice must obey the contract of
                    ...
public aspect CirclingPolygons {
   public double Polygon.getRadius()
   {...}
   public Point Polygon.getCenter()
   {......
Introduction
             Substitution Principle
                            Introductions must obey the
                 ...
public aspect PersistentAccount {
   after (Account a): target(a) &&
    call(* Account.setName()) {
      persistName(a.g...
Pointcut Inversion
                          Principle
               Pointcuts should not depend upon
                   ...
The Future of AOP



Friday, September 7, 2007                       77
Components and
                             Frameworks
            • Much hyped in the 90s
            • All or nothing pr...
«aspect»
                              «aspect»
                                            Client
              Client
  ...
Improved Architectures

            • High-level defines policy
            • Low-level defines details

        Better sepa...
Improved Architectures

            • Domain-Specific Languages for the high-level
            • Connect to low-level detai...
public class PersistenceDSL {
   public PersistenceDSL() {
    after()
    .calling(methodsIn(
      interface(StateChange...
Conclusions




Friday, September 7, 2007                 83
Real applications...

                mix multiple domains...

                     causing tangled code.

Friday, Septemb...
Objects alone don’t
                     prevent this tangling.



Friday, September 7, 2007                     85
Aspects modularize the
                    intersection
                  of the domains.



Friday, September 7, 2007    ...
Obvious uses:
                              Persistence
                              Transactions
                       ...
The future?

                            Better components and
                                 frameworks

              ...
Thank You!

                • dean@objectmentor.com
                • http://objectmentor.com
                • http://asp...
Upcoming SlideShare
Loading in...5
×

Aspect Oriented Programming and Design

4,457

Published on

Published in: Technology, News & Politics
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,457
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
165
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Aspect Oriented Programming and Design"

  1. 1. Aspect-Oriented Programming and Design For Java and AspectJ Dean Wampler Object Mentor, Inc. dean@objectmentor.com Friday, September 7, 2007 1
  2. 2. public class Account { public Money getBalance() {...} public void credit(Money m) {...} public void debit(Money m) {...} ... } Friday, September 7, 2007 2
  3. 3. For example... public void credit(Money m) { balance += m; } Friday, September 7, 2007 3
  4. 4. Clean and Simple Friday, September 7, 2007 4
  5. 5. However, Real applications need: Transactions public class BankAccount { public Money getBalance(){...} public void credit(Money m) {...} Persistence public void debit(Money m) {...} ... } Security Friday, September 7, 2007 5
  6. 6. Back to our example... public void credit(Money m) { if (unauthorized()) throw new ...(); Money saveBalance = balance; try { beginTransaction(); balance += m; persistBalance(balance); } ... Friday, September 7, 2007 6
  7. 7. ... } catch (...) { balance = savedBalance; } finally { endTransaction(); } } Friday, September 7, 2007 7
  8. 8. What’s wrong?? Friday, September 7, 2007 8
  9. 9. We’re mixing multiple domains, with fine-grained intersections. “tangled” code Transactions Persistence Security “Problem Domain” “scattered” logic Friday, September 7, 2007 9
  10. 10. Aspects restore modularity by encapsulating the intersections. Transaction Transactions Aspect Persistence Persistence Aspect Security Security Aspect Friday, September 7, 2007 10
  11. 11. Obvious uses: Persistence Transactions Security Logging others... Friday, September 7, 2007 11
  12. 12. Back to our example... public void credit(Money m) { balance += m; } Back to what we want... Friday, September 7, 2007 12
  13. 13. Back to our example... class-like declaration public aspect PersistentAccount{ pointcut newBalance ( bind variables Account a, Money newBal): set (Money Account.balance) && args (newBal) && this (a); remember “this” ... named set of “join points” remember new value any time “balance” is set Friday, September 7, 2007 13
  14. 14. Back to our example... “after advice” ... same arguments after ( Account a, Money newBal) : same newBalance(a, newBal) { pointcut persist(a, newBal); } body of the advice Friday, September 7, 2007 14
  15. 15. Types of advice before after returning after throwing after around Friday, September 7, 2007 15
  16. 16. Other terms • Join point • Pointcut • Advice • Cross-cutting concern • Introduction (a.k.a. Inter-type declaration) • Aspect Friday, September 7, 2007 16
  17. 17. Pure Java AOP Spring AOP JBoss AOP Friday, September 7, 2007 17
  18. 18. Spring AOP @AspectJ Support Friday, September 7, 2007 18
  19. 19. @Aspect class PersistentAccount { @Pointcut (“execution(* Account.*(..))”) private void newBalance() {} @After(“newBalance()”) private void persistChange() {...} } Friday, September 7, 2007 19
  20. 20. auto-configure @Aspects <aop:aspectj-autoproxy/> ... <bean id=”persistantAccount” class=”...PersistentAccount”> <!-- properties of bean --> </bean> The usual Spring bean stuff... Friday, September 7, 2007 20
  21. 21. <aop:config> Wire another advice using XML <aop:advisor pointcut=quot;....newBalance()quot; advice-ref=quot;tx-advicequot;/> </aop:config> <tx:advice id=quot;tx-advicequot;> <tx:attributes> <tx:method name=quot;*quot; propagation=quot;REQUIREDquot;/> </tx:attributes> </tx:advice> Friday, September 7, 2007 21
  22. 22. Spring’s Dependency Injection can also wire “POJO” aspects Friday, September 7, 2007 22
  23. 23. Recommendation: Use Spring to introduce AOP into your environment. Friday, September 7, 2007 23
  24. 24. JBoss AOP works in similar ways. Friday, September 7, 2007 24
  25. 25. Aspect-Oriented Design (Starting in the early years) Friday, September 7, 2007 25
  26. 26. “Classes should be oblivious to aspects.” Friday, September 7, 2007 26
  27. 27. However, this leads to... Friday, September 7, 2007 27
  28. 28. Persistence Aspect PCD: set (* *.name) X ??? Account Account first_name name last_name Version 1 Version 2 Friday, September 7, 2007 28
  29. 29. Aspects make initial version easier, But subsequent versions harder! Friday, September 7, 2007 29
  30. 30. ! AOP-Evolution x o d a r a P Friday, September 7, 2007 30
  31. 31. Obliviousness ... ... is like that. Friday, September 7, 2007 31
  32. 32. We forgot established OOD Principles. Friday, September 7, 2007 32
  33. 33. 11 Principles of OOD Friday, September 7, 2007 33
  34. 34. #1 Single Responsibility Principle A class should have only one reason to change. Friday, September 7, 2007 34
  35. 35. #2 Open-Closed Principle A module should be open for extension, but closed for modification. Friday, September 7, 2007 35
  36. 36. An Example... Friday, September 7, 2007 36
  37. 37. public interface Shape { public double getArea(); public void draw(); } Friday, September 7, 2007 37
  38. 38. public abstract class Polygon implements Shape { public Point getVertex(int index) {...} public void draw() {...} public String toString() {...} } Friday, September 7, 2007 38
  39. 39. public class Square extends Polygon { public double getArea() {...} } public class Rectangle extends Polygon { public double getArea() {...} } Friday, September 7, 2007 39
  40. 40. Square is a Rectangle? Isn’t it? Friday, September 7, 2007 40
  41. 41. An Aspect Refactoring... public interface Shape { public double getArea(); public void draw(); } Friday, September 7, 2007 41
  42. 42. public abstract class Polygon implements Shape { public Point getVertex(int index) {...} public void draw() {...} public String toString() {...} } Friday, September 7, 2007 42
  43. 43. package shapes.tostring; public aspect PolygonToString { public String Polygon.toString() {...} } Friday, September 7, 2007 43
  44. 44. package drawing; public interface Drawable { void draw(); } Friday, September 7, 2007 44
  45. 45. 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(); } Friday, September 7, 2007 45
  46. 46. #3 Liskov Substitution Principle Subtypes must be substitutable for their base types. Friday, September 7, 2007 46
  47. 47. Square is a Rectangle? What do the unit tests say? Friday, September 7, 2007 47
  48. 48. public RectangleDrawTest { extends ... public void testDraw { Shape[] shapes = new Shapes[] { new Rectangle(...), new Square(...)}; for (Shape s: shapes) s.draw(); // just works... } } Friday, September 7, 2007 48
  49. 49. Square is a Rectangle? Apparently, it is!! (at least in this context...) Friday, September 7, 2007 49
  50. 50. Mutability... Friday, September 7, 2007 50
  51. 51. Need to Change Polygon: public abstract class Polygon implements Shape { public Point getVertex(int index) {...} List<Point> getVertices() {...} } Occasionally need to break OCP... Package private! Friday, September 7, 2007 51
  52. 52. package shapes; // same package import ...; aspect MutablePolygon { public void Polygon.setHeight(int i) { List<Point> list = getVertices(); // Change appropriate points... } public void Polygon.setWidth(int i) {...} } Friday, September 7, 2007 52
  53. 53. Square is a Rectangle? Friday, September 7, 2007 53
  54. 54. public MutableRectangleTest ... { public void testSetWidth{ Point p00, p20, p25, p05 = ...; Rectangle rect = new Rectangle(p00,p20,p25,p05); (0,5) (2,5) (0,0) (2,0) Friday, September 7, 2007 54
  55. 55. 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()); } } Friday, September 7, 2007 55
  56. 56. Square is a Rectangle? Prove it! (or not...) Friday, September 7, 2007 56
  57. 57. What if I Use a Square? ... 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()); This won’t pass! Friday, September 7, 2007 57
  58. 58. Square is a Rectangle? Not in this context!! Friday, September 7, 2007 58
  59. 59. LSP Is Context Dependent! Friday, September 7, 2007 59
  60. 60. LSP Is the Basis for Design by Contract Friday, September 7, 2007 60
  61. 61. Shameless Plug... Friday, September 7, 2007 61
  62. 62. Contract4J: DbC for Java annotation-based @Contract public abstract class Polygon implements Shape { @Pre(“index>=0”) @Post(“$return != null”) public Point getVertex(int index) {...} } Friday, September 7, 2007 62
  63. 63. #5 Dependency Inversion Principle Abstractions should not depend upon details. Details should depend upon abstractions. Friday, September 7, 2007 63
  64. 64. Client Service Client Service Service Friday, September 7, 2007 64
  65. 65. Service Client Service «aspect» «aspect» Client Client ClientService ClientService Service Service Friday, September 7, 2007 65
  66. 66. New AOD Principles Friday, September 7, 2007 66
  67. 67. package shapes.tostring; public aspect PolygonToString { public String Polygon.toString() {...} } Do introductions violate OCP?? No Friday, September 7, 2007 67
  68. 68. Open-Closed Principle: Updated A module should be open for extension, but closed for source and contract modification. Friday, September 7, 2007 68
  69. 69. public aspect Tracer { before(): call(* Polygon.*(..)) { log(thisJoinPointStaticPart); } Similar! } public class LoggedPolygonDraws { public void draw() { log(“Polygon.draw”); super.draw(); } } Friday, September 7, 2007 69
  70. 70. Liskov Substitution Principle: Updated Subtypes and aspects + base types must be substitutable for their base types. Friday, September 7, 2007 70
  71. 71. public aspect PolygonMunger { before(Polygon p): target(p) && call(* Polygon.draw(..)) { p.addPoint(new Point(/*...*/)); } } Does this look safe?? Friday, September 7, 2007 71
  72. 72. Advice Substitution Principle Advice must obey the contract of the advised join point. Friday, September 7, 2007 72
  73. 73. public aspect CirclingPolygons { public double Polygon.getRadius() {...} public Point Polygon.getCenter() {...} } Huh?? Friday, September 7, 2007 73
  74. 74. Introduction Substitution Principle Introductions must obey the contract of the module. Friday, September 7, 2007 74
  75. 75. public aspect PersistentAccount { after (Account a): target(a) && call(* Account.setName()) { persistName(a.getName()); } } What happens when “name” is refactored to “firstName” and “lastName”?? Friday, September 7, 2007 75
  76. 76. Pointcut Inversion Principle Pointcuts should not depend upon concrete details. Pointcuts should depend upon abstractions. Friday, September 7, 2007 76
  77. 77. The Future of AOP Friday, September 7, 2007 77
  78. 78. Components and Frameworks • Much hyped in the 90s • All or nothing proposition • ... due to internal dependencies Can aspects reduce the coupling and make them more reusable? Friday, September 7, 2007 78
  79. 79. «aspect» «aspect» Client Client ClientService ClientService Service Service Friday, September 7, 2007 79
  80. 80. Improved Architectures • High-level defines policy • Low-level defines details Better separation using aspects? Friday, September 7, 2007 80
  81. 81. Improved Architectures • Domain-Specific Languages for the high-level • Connect to low-level details with aspects Friday, September 7, 2007 81
  82. 82. public class PersistenceDSL { public PersistenceDSL() { after() .calling(methodsIn( interface(StateChange.class))) .then(persistChange()); } } (Fanciful, made-up example...) Friday, September 7, 2007 82
  83. 83. Conclusions Friday, September 7, 2007 83
  84. 84. Real applications... mix multiple domains... causing tangled code. Friday, September 7, 2007 84
  85. 85. Objects alone don’t prevent this tangling. Friday, September 7, 2007 85
  86. 86. Aspects modularize the intersection of the domains. Friday, September 7, 2007 86
  87. 87. Obvious uses: Persistence Transactions Security Logging others... Friday, September 7, 2007 87
  88. 88. The future? Better components and frameworks Better architectures (Domain-specific languages) Friday, September 7, 2007 88
  89. 89. Thank You! • dean@objectmentor.com • http://objectmentor.com • http://aspectprogramming.com • http://contract4j.org • http://aquarium.rubyforge.org Friday, September 7, 2007 89
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×