Understanding Design Pattern Density with Aspects A Case Study in - - PowerPoint PPT Presentation

understanding design pattern density with aspects
SMART_READER_LITE
LIVE PREVIEW

Understanding Design Pattern Density with Aspects A Case Study in - - PowerPoint PPT Presentation

Understanding Design Pattern Density with Aspects A Case Study in JHotDraw with AspectJ Simon Denier, Pierre Cointe OBASCO Project cole des Mines de Nantes / INRIA ETAPS SC 2006 1 1 What is Pattern Density? From JUnit: a Cook's


slide-1
SLIDE 1

1 1

Understanding Design Pattern Density with Aspects

A Case Study in JHotDraw with AspectJ Simon Denier, Pierre Cointe

OBASCO Project École des Mines de Nantes / INRIA ETAPS SC 2006

slide-2
SLIDE 2

2 2

What is Pattern Density?

  • From “JUnit: a Cook's Tour”, Gamma & Beck
  • Mature frameworks show a high density of patterns
  • especially around key abstractions (TestCase in JUnit)
  • because patterns provide leverage to extend the framework
  • but they also make code harder to change (because of tangling)
  • “easier to use, harder to change”
  • What means “harder to change” exactly?
slide-3
SLIDE 3

3 3

Density, Composition, and Aspects

  • A high density most probably implies that some design

patterns compose together

  • Aspects enable modularization of crosscutting concerns
  • Hannemann et al shows some new modular, reusable

implementations of design patterns with AspectJ

  • Intuition: better modularization by aspects could ease, or

at least highlight, the composition of design patterns

slide-4
SLIDE 4

4 4

Incremental Approach with JHotDraw

  • JHotDraw: a framework for structured drawing
  • a design exercise with several design patterns (high density of

patterns around Figure, the key abstraction)

  • Our incremental approach:
  • isolate a base framework (more basic than the current one)
  • enhance the base with functions involving design patterns
  • have the option to come back to basic framework at no cost
  • for example, by a selection of modules at compile-time
  • Purpose: show the impact of design patterns composed

together without/with aspects

slide-5
SLIDE 5

5 5

Example: View observes Figures

  • Purpose: Figures notify View when they change, in order

to optimize redraw with their clipping area

aView aDrawing figure2 figure1 figure3 notify subjects

  • bserver
slide-6
SLIDE 6

6 6

Example: Observer aspect

aspect FigureOberver { /* Structure by Inter-Type Declaration (ITD) */ private Vector Figure.observers = new Vector(); /* Registration */ pointcut registerObserver(Figure f, View v): (...) after(Figure f, View v): registerObserver(f, v){ f.observers.add(v); } /* Notification Points */ pointcut changed(Figure f): this(f) && execution(void Figure+.move(..)); /* Notification Process */ after(Figure f): changed(f) { for (int i = 0; i < f.observers.size(); i++) f.observers.elementAt(i).invalidate(f); } }

  • General case (multiple observers per subject)
slide-7
SLIDE 7

7 7

Single View vs Multiple Views

slide-8
SLIDE 8

8 8

Singleton-Observer (1)

  • Single view on drawing and figures
  • Simplification of the Observer pattern when observer is a

Singleton (global access)

  • no structure to hold list of observers
  • no registration of observer
  • simple notification process

View.instance().invalidate(f);

  • Object impact: insert notification points in code
  • Simple implementation, easy to understand, simple to use
slide-9
SLIDE 9

9 9

Singleton-Observer (2)

  • Multiple views on drawing and figures
  • General case of Observer pattern
  • Object impact: invasive modifications
  • define list of observers in subjects
  • insert (de)registration points for observers
  • dispatch notification process
  • Notification points: same as for Singleton
  • Unfortunately, we have lost the simple collaboration with

singleton view

slide-10
SLIDE 10

10 10

Singleton-Observer with Aspects

  • Observer pattern is modularized in one aspect
  • Aspects can be easily plugged/unplugged
  • Solution:
  • provide two aspects, one general and one for the Singleton case
  • selection by user based on current configuration of framework

(single view or multiple views)

  • Future work: automatic selection based on detection of

Singleton?

slide-11
SLIDE 11

11 11

Composite-Decorator and Observer

  • Add GroupFigure (Composite) and BorderDecorator
  • build tree of Figures under Drawing
  • Problem: BorderDecorator modifies the clipping area of its

underneath Figure

  • the Figure knows when to notify
  • the view must get the clipping area from the BorderDecorator

aView aDrawing figure2 figure1 figure3 aGroupFigure aBorderDecorator

slide-12
SLIDE 12

12 12

Object Solution: O + C-D → CoR + C-D

  • Transform Observer into a Chain of Responsibility
  • a Figure notify its parent in the hierarchy of figures, either a

GroupFigure or a BorderDecorator

  • the Drawing stops the recursive process and notifies the view(s)
  • BorderDecorator can handle notifications from its child and

modify them aView aDrawing figure2 figure1 figure3 aGroupFigure aBorderDecorator

*

slide-13
SLIDE 13

13 13

Object Impact

  • BorderDecorator and GroupFigure become both
  • bservers and subjects
  • although GroupFigure is not primarely concerned
  • View is involved to stop the recursive process
  • All notifications must follow the chain
slide-14
SLIDE 14

14 14

O + C-D with Aspects

  • A change command defines a recursive control flow

whenever it is sent down the tree of Figures

  • use AspectJ pointcuts based on control flow (cflow)
  • Only the Observer aspect is modified
  • the impact is limited to pointcuts (contrary to the overall impact of

Chain of Responsibility)

  • Can we do better? Yes!
  • different pointcuts on different actions = different strategies for

notification (not just chained handling)

slide-15
SLIDE 15

15 15

Top-Level Observer

  • Notify only the top level action, because action necessarily

triggers a change (example: move action)

  • Simple (well-known) solution in AspectJ

pointcut changed (Figure f): this(f) && execution(void Figure+.move(..)) && !cflowbelow(execution(void Figure+.move(..)))

aView aDrawing figure2 figure1 figure3 aGroupFigure aBorderDecorator

slide-16
SLIDE 16

16 16

Path Observer (BorderDecorator)

  • get top-most BorderDecorator (the one which defines the overall

clipping area for the current action)

pointcut topmost(Figure f): this(f) && execution(void Figure+.setAttribute(..)) && !cflowbelow(execution(void Figure+.setAttribute(..)))

  • pass it on the underneath join point to replace the current Figure

pointcut changed(Figure f): cflowbelow(topmost(f)) && execution(void Figure+.setAttribute(..))

aView aDrawing figure2 figure1 figure3 aGroupFigure aBorderDecorator

slide-17
SLIDE 17

17 17

Impact of Pattern Density on Objects

  • What is “harder to change”?
  • Inner modification (Singleton-Observer)
  • Broad transformation on a set of classes (Chain of

Responsibility)

  • Invasive impact, the basic solution is lost
slide-18
SLIDE 18

18 18

Contributions of Aspects

  • Impact limited to one module or simply pointcuts
  • Adaptation is fine grained with pointcuts but has also a

large scale (a control flow across many objects)

  • allows reasoning on a large scale, even for small details
  • Aspects provide better modularization between classes
  • But the pointcut language is tailored to provide meaningful

adaptation following class relationships (e.g. cflow)

slide-19
SLIDE 19

19 19

Specificity of Aspects?

  • cflow constructs can be emulated if we have an inspector
  • n the execution stack
  • Inter-type declaration is akin to mixin inheritance or traits
  • So nothing specific, but well integrated into aspects
  • Why not integrate other mechanisms into language?
  • seek for expressiveness on common design pattern structure:

recursivity, indirection

slide-20
SLIDE 20

20 20

Questions?