Does obliviousness increase overall modularity? This presents the results of an empirical study that focuses on the tradeoffs between obliviousness and modularity. The results may surprise you!
Towards Reusable Components With Aspects [ICSE 2008]
1. Towards Reusable
Components with Aspects:
An Empirical Study on Modularity and Obliviousness
Kevin Hoffman / Patrick Eugster
2. Seen code that looks like this?
(Carlo H. Séquin @ Berkeley) (speedcubing.com)
(George W. Hart @ Stony Brook) (George W. Hart @ Stony Brook)
3. Roadmap
AOP with AspectJ
Challenges
Cooperative AOP with Explicit Join Points
Empirical Study
How obliviousness can be traded for increased
modularity and reuse through Cooperative AOP
Potential pitfalls and guidelines
4. Cross-cutting Concerns
(Thanks to AspectJ Dev Tools (AJDT) Visualization Eclipse Perspective)
5. Cross-cutting Concerns
(Thanks to AspectJ Dev Tools (AJDT) Visualization Eclipse Perspective)
10. AOP Stratagems [Filman/Friedman’00]
Obliviousness
Increased modularity of base code and aspect code
Parallel and domain-specific development
Better post-mortem extendibility
Quantification (pattern matching)
Reduction in code size and duplicity
Higher level interaction between primary and cross-
cutting concerns
11. AspectJ
AspectJ [Kiczales ’01]
Join point model
Structural points in ‘base code’
Quantification model (pointcuts)
Lexical patterns and type constraints
Dynamic predicates and control flow
Aspects inject advice before, after, around…
23. Explicit Join Points (EJPs)
Abstract a cross-cutting concern to its most
essential form
Invoke the information hiding principle
Model the abstraction explicitly using named
join points instead of implicit join points
Reference EJPs in code explicitly
Or use aspects to inject EJP references obliviously
26. Comparison of Approaches
AspectJ:
Base Code Aspects
AspectJ with EJPs (Cooperative AOP):
Library Interfaces Pluggable Libraries
Base Code EJP Interfaces Aspects
Scoped EJPs, pointcutargs and thisblock, advice
parameterization by type/value, and policy enforcement
27. Building Aspect Libraries with EJPs
Define semantic interfaces of cross-cutting
concerns using interfaces and EJPs
Package these in a JAR
Define aspects that advise the EJPs to
implement the cross cutting concerns
Package each implementation in a different JAR
Write base code or aspects to reference EJPs
Choose aspect implementation JAR at load-time
As the EJPs evolve, use aspects to obliviously
adapt calls from old EJPs to new EJPs
29. Sullivan—Levels of Obliviousness
Language-level (i.e. language support for AOP)
Feature obliviousness—base code unaware of
features in aspects, but do know of preconditions
Designer obliviousness—
Base code programmers blissfully unaware…
Pure obliviousness—
Complete, symmetric separation
30. This Empirical Study
What are the tradeoffs
between modularity
and obliviousness?
31. This Empirical Study
Refactored Exception Handling for 3 Java Apps:
Using AspectJ
Using EJPs / Cooperative AOP
Empirical Metrics Measuring:
Coupling & Cohesion
Size & Complexity
Separation of Concerns
Reusability
Revisiting ‘Exceptions and Aspects’ @ FSE06
[Filho et. al.] – Thanks!
32. Target Applications
Telestrada (Java)
220+ classes and interfaces, 3400 LOC
Java Pet Store (Java)
340+ classes and interfaces,17800 LOC
Health Watcher (AspectJ)
36 aspects, 96 classes and interfaces, 6600 LOC
Aspects for CC, distribution, persistence, some EH
33. Refactoring Strategy (AspectJ)
BEFORE AFTER
class C { aspect A {
void m() throws … { pointcut p():
try { /*body*/ } execution(void C.m());
catch(E e) { … } void around(): p() {
} try {
} proceed();
} catch (E e) { … }
}
declare soft: E: p();
}
class C {
void m(){ /*body*/ }
}
34. Refactoring Strategy (EJPs)
BEFORE AFTER
class C { aspect A {
void m() throws … { scoped joinpoint ejpH()
try { /*body*/ } handles E throws …;
catch(E e) { … } void around() throws …:
} call(ejpScope(ejpH))
} {
try{ proceed(); }
catch(E e) { … }
}
}
class C {
void m() throws … {
A.ejpH(){ /*body*/ }
}
}
35. Empirical Metrics
Coupling Between Modules (CBM)
Coupling on Intercepted Modules (CIM)
Lack of Cohesion of Operations (LCO)
Lines of Code (LOC) / Concern LOC (CLOC)
Number of Operations (NoO)
Concern Diffusion over Modules (CDoM)
Concern Diffusion over Operations (CDoO)
Concern Diffusion over Lines of Code (CDoLOC)
Reusable Operation Use Percentage (ROUP)
36. Coupling Metrics
Coupling Between Modules (CBM)
Number of other modules referenced via field access
or method call or EJP reference
Extended to include reference to EJP interfaces
[Chidamber, Kemerer 1994]
class C {
void m1(B var1, B var2) {
A.ejpH(){ var1.m3(); }
C.m2();
var2.m4();
CBM = 2
} (A and B)
static void m2() { … }
}
42. Size / Complexity Metrics
Lines of Code (LOC)
# of lines of code without whitespace / comments
Concern Lines of Code (CLOC)
# of lines of code required to implement the exception
handling concern
Number of Operations (NoO)
Number of declared methods and advice
46. Separation of Concern Metrics
Concern Diffusion over Modules (CDoM)
# of modules that implement a concern
… OR reference one that does
Concern Diffusion over Operations (CDoO)
# of operations that implement a concern
… OR reference one that does
49. Separation of Concern Metrics
Concern Diffusion over Lines of Code
# of transitions between one concern to another
class C { class C {
void m() throws … { void m() throws … {
try { A.ejpHandler() {
/* /*
body body
*/ */
} catch(E e) { … } }
} }
} }
51. % of handlers implemented by
abstract aspects or EJP library
Exception Handler Reuse
52. Reusable Exception Handler EJPs
Ignore exception
Print/log exception
Rethrow different exception or its cause
On exception set variable to value
Propagate exception if flagged
16 EJPs covered 74% of all handlers
54. Cooperative AOP Can Help
AspectJ: 39 AspectBase couplings
EJPs: 11 AspectInterface, 15 BaseInterface
55. Conclusions
Explicit Interfaces and EJP references:
Provided effective means for advice
parameterization
Greatly increased aspect reusability
Must be carefully designed, ideally in advance
Greatest software quality achieved when using
combination of obliviousness + EJPs
56. Future Work
JSR-308 includes
proposal for annotations
on statements
Study interactions
between obliviousness
and software quality in
the presence of multiple
cross-cutting concerns
kjhoffma@cs.purdue.edu
peugster@cs.purdue.edu
Download papers, slides, and compiler at http://www.kevinjhoffman.com/
58. Addressing EJP Explicitness
Use EJPs only when appropriate
Design EJPs so that their presence is minimal
Base Code EJP Interfaces Aspects
Use aspects to reference EJPs as appropriate
Aspect-oriented code editors
Fluid AOP [Hon / Kiczales]
59. Empirical Metrics Formulated…
Coupling, Cohesion, Separation of Concerns
On the reuse and maintenance of Aspect-Oriented
software: [Sant’Anna et. al. 2000]
AspectBase Code Coupling
Measuring the effects of software aspectization
[Ceccato/Tonella 2004]
http://aopmetrics.tigris.org/
60. Empirical Studies Emerging…
Separation of Concerns in Multi-agent Systems: An
Empirical Study [2004]
Modularizing design patterns with aspects: a quantitative
study [AOSD’05]
Composing design patterns: a scalability study of aspect-
oriented programming [AOSD’06]
Exceptions and aspects: the devil is in the details [FSE’06]
On the impact of aspectual decompositions on design
stability: An empirical study [ECOOP’07]
Towards Reusable Components with Aspects [ICSE’08]
Evolving Software Product Lines with Aspects [ICSE’08]
61. Explicit Join Point Declarations
abstract aspect TranConcern {
scoped joinpoint void enterTrans(int isolation)
throws TranException;
} Keyword to Explicit Name to Associate
Declare EJP with Abstract Semantics
Optional Constraints Acting Explicit Value
Modifiers Upon Base Code Parameterization
62. Referencing EJPs in Base Code
abstract aspect TranConcern {
scoped joinpoint void enterTrans(int isolation)
throws TranException;
joinpoint int defIso() = 1; Some policy aspect could
} implement/override this EJP
void someMethod() throws TranException {
TranConcern.enterTrans(TranConcern.defIso()) {
//block of code
} Reference to scoped EJP; Reference to
} entire block of code is advised EJP in base code
64. Advising EJPs in Aspects
aspect BillingComponentsTranPolicy {
int around(): call(ejp(TranConcern.defIso))
&& within (com.me.billing.*)
{ return 4; } //use a higher isolation level in billing pkg
}
aspect ForceIsolationLevel {
int around(): call(ejp(TranConcern.defIso))
&& cflow(call(* CreditCard+.*(..)))
{ return 5; } //anytime the call stack includes a method
} //from the CreditCard class use iso level 5