UvA-DARE (Digital Academic Repository) Fluoride-releasing … · o.o. EE oo UU oo oo oo
Features Meet Aspects Software Development with. 2 Motivation for CaesarJ … OO languages lack...
-
Upload
berniece-douglas -
Category
Documents
-
view
212 -
download
0
Transcript of Features Meet Aspects Software Development with. 2 Motivation for CaesarJ … OO languages lack...
Features Meet Aspects Software Development with
2
Motivation for CaesarJ …
• OO languages lack support for:– Higher-level modules beyond classes to capture features– Crosscutting composition of features
• AO languages have support for crosscutting composition– But they poorly support feature modularization and
refinement
3
Higher-Level Modules ...
• Existing languages lack sufficient means for organizing collaborating classes– e.g., packages and namespaces
• Problems– no means to express variants of a collaboration– no polymorphism– no runtime semantics
• Mechanisms that proved useful for single classes not available for sets of collaborating classes
4
Higher-Level Modules ...
Example: a component for displaying hierarchical structures getRoot()
generateLayout()draw(g)refresh()
HierarchyDisplay
getText()textFits(text)calculateLayout()initShape(pt)draw(g)
shape: Shape
Node
getChildAt(int)getChildCount()calculateLayout()draw(g)
CompositeNode
init(parent, child)initShape(pt)draw(g)
conn: Connector
Connection
0-*connections
parent
child
0-*
children… can you imagine putting it into one class-like module?
5
Higher-Level Modules ...
… can you imagine extending the hierarchy display component … by overriding only affected classes,
… just as one extends single classes by overriding affected methods?
getRoot()generateLayout()draw(g)refresh()
HierarchyDisplay
getText()textFits(text)calculateLayout(..)positionNode(..)initShape(..)draw(g)
shape: Shape
Node
getChildAt(int)getChildCount()calculateLayout()draw(g)
CompositeNode
init(parent, child)initShape(pt)draw(g)
conn: Connector
Connection
0-*connections
parent
child
0-*
children
AdjustedHierarchyDisplay
textFits(text)positionNode(..)
maxWidth: int
Node
CompositeNode
Connection
0-*connections
parent
child
0-*
children
6
C1
C2 C3
C4
C5
P1
P2
P3
C1
C3
C2
C4
APPL 1 APPLn
with a family of applications in a
domain
generic component
Crosscutting Composition …
7
getCEO()getDepartmentAt()getDepartmentCount()addDepartment()appointCEO()exchangeRoles()
Company
getDepartment()getFullName()getRole()getSex()assignTo()leaveDepartment()setRole()
namerolesex
Employee
getManager()getName()getWorkerAt()getWorkerCount()appointManager()registerWorker()unregisterWorker()
name
Department
0-*
ceo11 manager
0-*
1
workers
CompanyModel HierarchyDisplay
getRoot()generateLayout()
draw(g)refresh()
getText()
textFits(text)calculateLayout()
initShape(pt)draw(g)
shape: Shape
Node
getChildAt(int)getChildCount()calculateLayout()
draw(g)
CompositeNode
init(parent, child)initShape(pt)
draw(g)
conn: Connector
Connection
0-*connections
parent
child
children
Crosscutting Composition ...
… want to use for displayng a company’s structure …
CEO
Department Managers
Workers
and for a window’s structure …
8
Aspects of Crosscutting Composition
Company
Employee
Department
0-*
ceo1 1 manager
0-*
1
workers
adopt generic display logic for company model
after certain changes refresh display or recalculate layout
behavioral mapping needed
behavioral mapping needed
getRoot()generateLayout()draw(g)refresh()
HierarchyDisplayImpl
getText()textFits(text)calculateLayout()initShape(pt)draw(g)
Node
getChildAt(int)getChildCount()calculateLayout()draw(g)
CompositeNode
init(parent, child)initShape(pt)draw(g)
Connection
0-*connections
parent
child
0-*
children
structural mapping needed
structural mapping needed
Let us try patterns …
9
Patterns for Integration…
getRoot()draw()setView()refresh()generateLayout()
view : JComponent
HierarchyDisplay
Adapters
getRoot()
root : Company
CompanyHierarchyDisplay
getText()getChildAt()getChildCount()
wrappee : Company
CompanyNode
getText()getChildAt()getChildCount()
wrappee : Department
DepartmentNode
getText()
wrappee : Employee
EmployeeNode
getText()textFits(text)calculateLayout()initShape(pt)draw(g)
shape: Shape
Node
getChildAt(int)getChildCount()calculateLayout()draw(g)
CompositeNode
Company EmployeeDepartment0-*
ceo 11manager
0-*1
workerscast down toCompanyNode
cast down toEmployeeNode
cast down toDepartmentNode
10
Patterns for Integration…
Observers
getRoot()companyChanged()departmentChanged()departmentRemoved()workerAdded()workerRemoved()employeeChanged()
root : Company
CompanyHierarchyDisplay
addObserver()removeObserver()
observers
Company
addObserver()removeObserver()
observers
Employee
addObserver()removeObserver()
observers
Department
0-*
ceo 1
1manager
0-*1
workers
employeeChanged()
EmployeeObserver
departmentChanged()workerAdded()workerRemoved()
DepartmentObserver
companyChanged()deparmentAdded()departmentRemoved()
CompanyObserver
0-* 0-*
0-*
11
CaesarJ in a Nutshell …
Component A
A B
C D
Component B
E F
G… beyond “typical crosscutting concerns“ (security, persistence …)
… focus on feature modularization, extension and integration
aspects and features inside
12
OutlineOutline
► Multi-class modules and hierarchical refinementsMulti-class modules and hierarchical refinements Defining and extending components with virtual Defining and extending components with virtual
classesclasses Hierarchical compositionHierarchical composition
► Crosscutting compositionCrosscutting composition Defining wrapper classesDefining wrapper classes Observing events with pointcutsObserving events with pointcuts Aspects as classesAspects as classes Dynamic aspect deploymentDynamic aspect deployment Variability managementVariability management
► State of the artState of the art
13
Virtual Classes
• Originates in Beta [Madsen et al]
• Idea:
Give inner classes the same status as (virtual) methods
Overriding and late binding should also apply to nested classes, similarly to overriding and late binding of methods.
• Consequence:
Virtual classes are properties of objects of the enclosing class– Talk about class expr.C, similarly to method expr.m()
14
Virtual Classes - Examplecclass HierarchyDisplayImpl { cclass Node {} cclass CompositeNode extends Node { ... } cclass Connection { void positionNode() {...} } void foo(Node n) { Connection c = new Connection(); }}
cclass HierarchyDisplayImplA extends HierarchyDisplayImpl { cclass Node { int maxwidth; ... } void foo(Node n) { … n.maxwidth … }}
cclass HierarchyDisplayImplB extends HierarchyDisplayImpl { cclass Connection { void positionNode() { … super.positionNode(); …} }}
15
Virtual Classes - Examplecclass HierarchyDisplayImpl { cclass Node {} cclass CompositeNode extends this.Node { ... } cclass Connection { void positionNode() {...} } void foo(this.Node n) { this.Connection c = this.new Connection(); }}
cclass HierarchyDisplayImplA extends HierarchyDisplayImpl { cclass Node extends super.Node { int maxwidth; ... } void foo(this.Node n) { … n.maxwidth … }}
cclass HierarchyDisplayImplB extends HierarchyDisplayImpl { cclass Connection extends super.Connection { void positionNode() { … super.positionNode(); …} }}
Implicit Scoping!
16
Virtual Classes - Example
…if instance of HierarchyDisplayImplA
cclass HierarchyDisplayImpl { cclass Node {} cclass CompositeNode extends this.Node { ... } cclass Connection { void positionNode() {...} } void foo(this.Node n) { this.Connection c = this.new Connection(); }}
cclass HierarchyDisplayImplA extends HierarchyDisplayImpl { cclass Node extends super.Node { int maxwidth; ... } void foo(this.Node n) { … n.maxwidth … }}
cclass HierarchyDisplayImplB extends HierarchyDisplayImpl { cclass Connection extends super.Connection { void positionNode() { … super.positionNode(); …} }}
17
Virtual Classes - Example
…if instance of HierarchyDisplayImplB
cclass HierarchyDisplayImpl { cclass Node {} cclass CompositeNode extends this.Node { ... } cclass Connection { void positionNode() {...} } void foo(this.Node n) { this.Connection c = this.new Connection(); }}
cclass HierarchyDisplayImplA extends HierarchyDisplayImpl { cclass Node extends super.Node { int maxwidth; ... } void foo(this.Node n) { … n.maxwidth … }}
cclass HierarchyDisplayImplB extends HierarchyDisplayImpl { cclass Connection extends super.Connection { void positionNode() { … super.positionNode(); …} }}
18
Virtual Classes - Example
No type cast necessary
cclass HierarchyDisplayImpl { cclass Node {} cclass CompositeNode extends this.Node { ... } cclass Connection { void positionNode() {...} } void foo(this.Node n) { this.Connection c = this.new Connection(); }}
cclass HierarchyDisplayImplA extends HierarchyDisplayImpl { cclass Node extends super.Node { int maxwidth; ... } void foo(this.Node n) { … n.maxwidth … }}
cclass HierarchyDisplayImplB extends HierarchyDisplayImpl { cclass Connection extends super.Connection { void positionNode() { … super.positionNode(); …} }}
19
Composition of ExtensionsHierarchyDisplayImpl
Node
CompositeNode
Connection
0-*connections
parent
child 0-*
children
HierarchyDisplayImplA
Node
CompositeNode
Connection
0-*connections
parent
child 0-*
children
HierarchyDisplayImplB
Node
CompositeNode
Connection
0-*connections
parent
child 0-*
children
HierarchyDisplayImplAB
Node
CompositeNode
Connection
0-*connections
parent
child 0-*
children
• Can compose classes via „&“ operator
• Class composition via mixin linearization
cclass HierarchyDisplayAB extends HierarchyDisplayA & HierarchyDisplayB
20
Propagating Mixin Composition
• Class composition and virtual classes interact by means of their respective influence/dependency on this and super.
– Composition: this refers to the composed class, super is determined by mixin linearization.
– Virtual Classes: All virtual type annotations are declared via the enclosing this and super, respectively.
21
Composition of Layers
HdB.Node
Hd.CompNodeHd.Connection
CompNode NodeConnection
HdA.Connection
Hd.Node
cclass HierarchyDisplayImplAB extends HierarchyDisplayImplA & HierarchyDisplayImplB {}
22
Composition of Layers
HdB.Node
Hd.CompNodeHd.Connection
CompNode NodeConnection
HdA.Connection
Hd.Node
cclass HierarchyDisplayImplAB extends HierarchyDisplayImplA & HierarchyDisplayImplB {}
23
Family Polymorphism
• Subclasses are subtypes!
hd.Node findChild(final HdI hd, hd.CompositeNode n, String str) { for (int i = 0; i < n.getChildCount(); i++) hd.Node m = n.getChildAt(i); if (m.getText().equals(str)) return m; } return null;}...
final HierachyDisplayA hda = new HierarchyDisplayA();hda.CompositeNode cna = …;
final HierachyDisplayB hdb = new HierarchyDisplayB();hdb.CompositeNode cnb = …;
hda.Node n = findChild(hda, cna, someString); // okhdb.Node n = findChild(hdb, cnb, someString); // okhda.Node n = findChild(hdb, cna, someString); // static error
24
Family Polymorphism
• In our case, objects can be repositories of collaborating classes
• Type system makes sure that objects from different families never mix!– Otherwise we could easily produce type errors
• Type system uses „path-dependent types“– Type name is prefixed with path to family– All fields in a path must be „final“
final HierarchyDisplay hd = new HierarchyDisplayA();final HierarchyDisplay hd2 = new HierarchyDisplayB();hd.Node n = hd.new Node(); // okhd.foo(n); // okhd2.Node n = hd.new Node(); // static errorhd2.foo(n); // static error
25
OutlineOutline
► Hierarchical RefinementsHierarchical Refinements Extending component with virtual classesExtending component with virtual classes Combining different extensionsCombining different extensions Feature-oriented decompositionFeature-oriented decomposition
► Crosscutting IntegrationCrosscutting Integration Defining wrapper classesDefining wrapper classes Observing events with pointcutsObserving events with pointcuts Variability managementVariability management
► State of the artState of the art
26
Feature Integration
Company
Employee
Department
0-*
ceo1 1 manager
0-*
1
workers
Display uses data and relationships of company objects
After certain changes display must be refreshed or layout recalculated
structural mapping
Design Goal:Keep components independent of each other
getRoot()generateLayout()draw(g)refresh()
HierarchyDisplay
getText()textFits(text)calculateLayout()initShape(pt)draw(g)
Node
getChildAt(int)getChildCount()calculateLayout()draw(g)
CompositeNode
init(parent, child)initShape(pt)draw(g)
Connection
0-*connections
parent
child
0-*
children
behavioral mapping
27CompanyHierarchyDisplay
CompanyHierarchyBinding
Node
CompositeNode
CompanyNode
DepartmentNode
WorkerNode
HierarchyDisplay
Node
CompositeNode
Connection
0-*connections
parent
child 0-*
children
Feature Integration
Company
Employee
Department
0-*
ceo1 1 manager
0-*
1
workers
Collaboration Interface
Binding toCompany Model
Concrete Component
VisualizationConcern
getRoot()calculateLayout()draw()setView()refresh()
IHierarchyDisplay
getText()textFits()textChanged()
Node
getChildAt()getChildCount()childrenChanged()
CompositeNode
28
Feature Integration - BindingsAdapting company model objects to visual nodes
refresh()...
CompanyHierarchyBinding
textChanged()...
Node
childrenChanged()...
CompositeNode
getText()getChildAt()getChildCount()
DepartmentNode
getText()getChildAt()getChildCount()
CompanyNode
getText()
WorkerNode
Company
Employee
Department
0-*
ceo
1
1 manager
0-*
1
wraps
wraps
wraps
cclass WorkerNode extends Node wraps Employee { String getText() { return wrappee.getFullName(); } }
29
Wrapper Recycling
cclass CompanyHierarchyBinding { cclass WorkerNode extends Node wraps Employee { ... } ... }
void test() { CompanyHierarchyBinding hier = new CompanyHierarchyDisplay();
Employee anna = new Employee();
assert(hier.WorkerNode(anna) == hier.WorkerNode(anna));
Employee peter = new Employee();
assert(hier.WorkerNode(anna) != hier.WorkerNode(peter)); }
wrapper is created on demand
wrapper is reused for the same object
wrapper is destroyed by garbage collector
30
refresh()...
CompanyHierarchyBinding
textChanged()...
Node
childrenChanged()...
CompositeNode
getText()getChildAt()getChildCount()
DepartmentNode
getText()getChildAt()getChildCount()
CompanyNode
getText()
WorkerNode
Company
Employee
Department
0-*
ceo
1
1 manager
0-*
1
wraps
wraps
wraps
Feature Integration - Pointcuts
After certain changes display must be updated
Call after children changed
Call after text change
Call when redraw is needed
31
Changes in Company Model
getCEO()getDepartmentAt()getDepartmentCount()setCEO()addDepartment()removeDepartment()transferTo()
Company
getDepartment()getFullName()getInitials()getRole()getSex()setName()setFirstName()setLastName()setRole()setDepartment()
Employee
getName()getManager()getWorkerAt()getWorkerCount()setName()setManager()addWorker()removeWorker()
Department
0-*
ceo11
manager
0-*
1workers
Affects text of a node
Affects children of a node
No direct effect
32
Observing Changes in Company Model
pointcut departmChildrenChange() : execution( Department.addWorker(..)) || execution( Department.removeWorker(..));
pointcut companyChildrenChange() : execution( Company.addDepartment(..)) || execution( Company.removeDepartment(..));
pointcut displayChange() : execution( company..setName(..)) || departmChildrenChange() || companyChildrenChange();
after(Department d) : departmChildrenChange() && this(d) { DepartmentNode(d).calculateLayout();}
after(Company c) : companyChildrenChange() && this(c) { CompanyNode(c).calculateLayout();}
after() : displayChange() && !cflowbelow(displayChange()) { refresh(); }
33
Support for Variability
• Several dimensions of variations– Two dimensions in our example:
•HierarchyDisplay implementation variations• Data model variations
• All defined to a common interface– Implement different facets of the interface– All parameterized over other facets
• Collaboration interface abstraction makes them composable
34
Combining Variations
IHierarchyDisplay
HierarchyDisplay
Angular-HierarchyDisplay
CompanyHierarchyBinding
Collaboration Interface Component Bindings
Component Implementations Components
CompanyHierarchyDisplay
Adjusted-CompanyHierarchyDisplay
Angular-CompanyHierarchyDisplay
AdjustedAngular-CompanyHierarchyDisplay
GUIHierarchyBinding
Adjusted-HierarchyDisplay
AdjustedAngular-HierarchyDisplay
GUIHierarchyDisplay
Adjusted-GUIHierarchyDisplay
Angular-GUIHierarchyDisplay
AdjustedAngular-GUIHierarchyDisplay
35
CaesarJ Aspects are Objects
• Aspects can be instantiated and referenced as any other object
• References to aspects can be polymorphic– aspectual polymorphism
• Multiple instances of an aspect can be created and used simultaneously
• Aspects can contain state– To parameterize their behavior– To accumulate results of observation
• Aspects can be deployed on different scopes
36
CaesarJ Aspects are Objects
• Aspects in CaesarJ are classes that have pointcuts and advice
• Keyword deployed creates and activates a singleton instance of the class
public deployed cclass CompanyChangeTracer {
pointcut change() : execution(void company.*.set*(..)) || execution(void company.*.add*(..)) || execution(void company.*.remove*(..)) || execution(void Company.transferTo(..));
after(Object o): change() && this(o) { System.out.println( "Object '" + o.toString() + "' changed"); }}
37
Dynamic Aspect Deployment
CompanyChangeTracer asp1 = new CompanyChangeTracer();
CompanyChangeTracer asp2 = new CompanyChangeTracer();
dept.setName(“DeptA”); /* not intercepted */
deploy asp1;dept.setName(“DeptB”); /* intercepted by asp1 */
deploy asp2;dept.setName(“DeptC”); /* intercepted by asp1 and asp2 */
undeploy asp1;undeploy asp2;dept.setName(“DeptD”); /* not intercepted */
38
Aspect Scoping
Thread local deployment:
Object local deployment:
CompanyChangeTracer asp1 = new CompanyChangeTracer();deploy(asp1) { new deptm.setName(“DeptA”); }
CompanyChangeTracer asp1 = new CompanyChangeTracer();CompanyChangeTracer asp1 = new CompanyChangeTracer();Department dept1 = new Department(“deptA”);Department dept2 = new Department(“deptB”);DeploySupport.deployOnObject(asp1, dept1);DeploySupport.deployOnObject(asp2, dept2);dept1.setName(“deptC”); /* intercepted by asp1 */dept2.setName(“deptD”); /* intercepted by asp2 */dept3.setName(“deptF”); /* not intercepted */DeploySupport.undeployFromObject(asp1, dept1);DeploySupport.undeployFromObject(asp2, dept2);
39
Integrating Distributed Components
method calls
rmi://server.net/Company
host.deployAspect(h)
advice calls
HierarchyDisplay
IHierarchyDisplay
CompanyHierarchyDisplay
CompanyHierarchyBinding
ClientServer
Company
Employee
Department
0-*
ceo
1
1 manager
0-*
1
40
Remote Aspect Deployment
CaesarHost host = new CaesarHost(“rmi://localhost/”);host.activateAspectDeployment();
Server side:
• Use execution pointcut, because calls can cross process boundaries
• Pointcut cflow cannot cross thread boundaries• Prepare aspect classes with Caesar RMI compiler
CaesarHost host = new CaesarHost(“rmi://localhost/”);ICompanyHierarchyDisplay hier = new CompanyHierarchyDisplay();host.deployAspect(hier);...host.undeployAspect(hier);
Client side:
41
Deployment on a Distributed Flow
deployed public cclass CompanyDisplayLogging { void around(): execution(draw(..)) && this(CompanyHierarchyDisplay) { CompanyLogger logger = new CompanyLogger(); deploy (logger) { proceed(); } }}
deployed public cclass CompanyDisplayLogging { void around() : execution(draw(..)) && this(CompanyHierarchyDisplay) { CompanyLogger logger = new CompanyLogger(); RemoteDeployment.deployOnControlFlow(logger); proceed(); RemoteDeployment.undeployFromControlFlow(logger); }}
42
OutlineOutline► Hierarchical RefinementsHierarchical Refinements
Extending component with virtual classesExtending component with virtual classes Combining different extensionsCombining different extensions Feature-oriented decompositionFeature-oriented decomposition
► Crosscutting IntegrationCrosscutting Integration
Defining wrapper classesDefining wrapper classes Observing events with pointcutsObserving events with pointcuts Variability managementVariability management
► State of the artState of the art
43
CaesarJ Development Tools
• CaesarJ IDE is available as a Eclipse plug-in– Integrated compiler and editor– Specialized visualization – Debugging support
44
More on CaesarJ
• Visit http://caesarj.org for more information– Download plug-in and examples– Read documentation and tutorial– Subscribe to mailing list
• Case studies– An interpreter of an experimental OO language– A real-time computer game– Access Control Service (by KU-Leuven, Belgium)– Mobile order management system (running)
45
References• E. Ernst, K. Ostermann and W. Cook. A Virtual Class Calculus. ACM Symposium on Principles of
Programming Languages (POPL'06), ACM SIGPLAN-SIGACT, 2006.• I. Aracic, V. Gasiunas, M. Mezini and K.Ostermann. Overview of CaesarJ. Transactions on Aspect-
Oriented Software Development I. LNCS, Vol. 3880, pp. 135 - 173, Feb 2006.• M. Mezini and K. Ostermann. Variability Management with Feature-Oriented Programming and Aspects.
Foundations of Software Engineering (FSE-12), ACM SIGSOFT, 2004. • M. Mezini and K.Ostermann. Conquering Aspects with Caesar.
In (M. Aksit ed.) Proceedings of the 2nd International Conference on Aspect-Oriented Software Development (AOSD)2003, ACM Press, pp. 90-100.
• M. Mezini and K. Ostermann. Integrating Independent Components with On-Demand Remodularisation. 17th ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOSPLA), 2002, Sigplan Notices, 37 (11), pp. 52 - 67.
• M. Mezini, L. Seiter, K. Lieberherr. Component Integration with Plug-and-Play Adapters. In M. Aksit (ed.) "Software Architectures and Component Technology: The State of the Art in Software Development", Kluwer Academic Publishers
• S´. Herrmann and M. Mezini. LAC: Aspectual Components in Lua. Workshop on Advanced Separation of Concerns, International Conference on Software-Engineering 2001 (ICSE '01)
• S. Herrmann and M. Mezini. Connectors for bridging mismatches between the components of a software engineering environment. IEE Proceedings - Software Engineering Special Issue: Aspect-oriented and component-based Software Development
• S. Herrmann and M. Mezini. Pirol: A Case-Study for Multi-Dimensional Separation of Concerns in Software-Engineering Environments. ACM Conference on Object-Oriented Programming, Systems, Languages and Applications (OOPSLA '00), Sigplan Notices, Vol. 35, No. 10
• L. Seiter, M. Mezini and K. Lieberherr. Dynamic Component Gluing. Proceedings of the 1st International Conference on Generative and Component-Based Software Engineering (GCSE '99)}, LNCS 1477
• M. Mezini and K. Lieberherr. Adaptive Plug-and-Play Components for Evolutionary Software Development. ACM 13th Annual Conference on Object-Oriented Programming, Systems, Languages and Applications (OOPSLA '98), Vancouver, Sigplan Notices, Vol. 33, No. 10., pp. 97-116.
• K. Lieberherr D. Lorenz, M. Mezini. Programming with Aspectual Components. Tech. Report. College of Computer Science, Northeastern University
46
People
• Project Leads– Prof. Mira Mezini – Prof. Klaus Ostermann
• Developers– Ivica Aracic – Vaidas Gasiunas – Karl Klose – Thiago Tonelli Bartolomei – Christian Meffert – Jochen Ungers – Daniel Zwicker – Andreas Wittmann – Walter A. Werner – Jürgen Hallpap
Klaus Osterman
n
Vaidas GasiunasIvica Aracic
Mira Mezini
47
http://caesarj.org
Thank you!