Title: Semantics of Edge Visitor Methods
1Semantics of Edge Visitor Methods
2Kinds of edge methods
- construction edges
- cbefore / cafter / caround
- repetition edges
- rbefore / rafter / raround
- strategy edges
- sbefore / safter / saround
- In the following focus is on before methods.
3Instead of code on construction edges
- Pattern matching capability
- if traversal context object has property P, then
execute code.
4Edge methods
- 0 stars
- -gt Source, x, Target
- void cbefore_x(Source s, Target t)
- 1 star
- -gt Source, x,
- void cbefore_x(Source s, Object t)
- -gt Source, , Target
- void cbefore(Source s, String partName,
Target t) - -gt , x, Target
- void cbefore_x(Object s, Target t)
5Edge methods
- 2 stars
- -gt Source, ,
- void cbefore(Source s, Object t)
- -gt , x,
- void cbefore_x(Object s,Object t)
- -gt , , Target
- void cbefore(Object s, String partName,
Target t) - 3 stars
- -gt , ,
- void cbefore(Object s, String partName, Object
t) -
6ExampleAdvice on all construction edges
- void cbefore(Object s, String partName, Object
t) - // print a message whenever a construction edge
- // is traversed
- System.out.println(
- source s.getClass().getName()
- partname partname
- target t.getClass().getName())
-
-
7Alternative design
- Add method to class Visitor to ask about the
currently active construction edge.
8Addition to Visitor
- has a method
- CEdge getCEdge()
- that returns the CEdge of the
- current or most recent construction edge being
traversed. The motivation is to fill in the
blanks about the edge being traversed. The
interface of cbefore may not uniquely determine
an edge. DJ now also supports edge patterns.
9Example
- void cbefore(Source s)
- -gt Source, ,
- This s an example of a cbefore method on a
construction edge that maps several edges.
getCEdge() will give us the details of the
current edge and the programmer may use
conditional statements to make the behavior
dependent on the details of the edge.
10CEdge
- CEdge
- ltsourceNamegt String
- ltpartNamegt String
- lttargetNamegt String
- ltedgeKindgt String.
- // derived / public, protected, private
11Visitor Methods forConstruction Edges
- void cbefore_x(Source s, Target t)
- -gt Source,x,Target
- void cbefore(Source s, Target t)
- -gt Source, , Target
- void cbefore_x(Source s)
- -gt Source, x,
- void cbefore(Source s)
- -gt Source, ,
All but the first method needs getCEdge to
get edge details.
12Visitor Methods forConstruction Edges
- void cbefore_x(Target t)
- -gt ,x,Target
- void cbefore(Target t)
- -gt ,,Target
- void cbefore_x()
- -gt ,x,
- void cbefore() // all edges
- -gt ,,
13Visitor Methods forStrategies
- void sbefore(Strategy s) // strategy
- is executed before the traversal corresponding to
s is started. More precisely, if the current
object graph node is currently not in the scope
of s, but it will be after the next traversal
step (going through an edge in the object graph),
the code of the sbefore method will be executed
before the next traversal step. - void safter(Strategy s) // strategy
- is executed after the traversal corresponding to
s is finished. More precisely, if s the current
object graph node is currently in the scope of s,
but it will not be after the next traversal step
(going through an edge in the object graph), the
code of the safter method will be executed before
the next traversal step.
14Class Dictionary
- Person Brothers Sisters Status.
- Status Single Married.
- Single .
- Married ltmarriedTogt Person.
- Brothers Person.
- Sisters Person.
15Strategy
- from Person bypassing Person
- through Married
- bypassing Person
- through Person
- bypassing Person
- through Brothers, Sisters
- bypassing Person
- to Person
16Strategy and Traversal States
- Person -gt Married bypassing Person
- Married -gt Person bypassing Person
- Person -gt Brothers bypassing Person
- Person -gt Sisters bypassing Person
- Brothers -gt Person bypassing Person
- Sisters -gt Person bypassing Person
- void before (Person h)
- if (previousSEdges()) print(h.getName())
else - if (previousSEdges(Married-gtPerson))
- print(spouseh.getName()) else
- if (previousSEdges(Brothers-gtPerson))
- print(brother-in-lawh.getName())else
- if (previousSEdges(Sisters-gtPerson))
- print(sister-in-lawh.getName())
-
17Strategy and Traversal States
- Person -gt Married bypassing Person
- Married -gt Person bypassing Person
- Person -gt Brothers bypassing Person
- Person -gt Sisters bypassing Person
- Brothers -gt Person bypassing Person
- Sisters -gt Person bypassing Person
- void before (Person h)
- if (nextSEdges(Person-gtMarried))
print(h.getName()) else - if (nextSEdges(Person-gtBrothers,Sisters))
- print(spouseh.getName()) else
- if (previousSEdges(Brothers-gtPerson))
- print(brother-in-lawh.getName())else
- if (previousSEdges(Sisters-gtPerson))
- print(sister-in-lawh.getName())
-
18Giving access to pathsin visitor objects
- Object graph path OPath
- Class graph path CPath
- Strategy graph path SPath
- methods available for looking at path and
retrieving objects. - For OPath retrieve objects by name WandVisitor
simulation.
19Traversal Context Object
- Traversal passes this to visitor.
20Programming with Strategies
- Strategies are abstractions of class graphs and
it is useful to program directly with those
abstractions. Therefore we extend DJ in two ways
by allowing - to check whether the traversal is currently in
the scope of a subtraversal - if (SEdges(sg)) (e.g., inside a cbefore
method) checks whether the currently active
strategy graph edges are contained in the
strategy sg. Notice that e.g. during the
traversal of an object graph edge, multiple
strategy graph edges may be active. - edge methods on strategies
21Programming with Strategies
- to check whether the traversal is currently in
the scope of a subtraversal - We want to talk about the state of the traversal
in before methods. This allows us to distinguish
how we arrived at an object graph node. - edge methods on strategies
- Strategies are built out of simpler strategies.
We want to attach before and after code to the
simpler strategies.
22Programming with Strategies
- At a given point during the traversal a set of
strategy graph edges is active. I think of it as
the strategy edges corresponding to traversal
graph edges on which a token travels. But there
is a more direct explanation the set of strategy
graph edges that are needed for the expansion
into object paths. - The following example illustrates the concept of
active strategy graph edges. Basically when
several tokens are distributed in different
copies of the class graph inside the traversal
graph, several edges are active.
23Short-cut
Active strategy graph edges A -gt B for A-gtx1X
strategy A -gt B B -gt C
Object graph
Object graph
Traversal graph
a1A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
Used for token set and currently active object
c3C
24Short-cut
Active strategy graph edges A -gt B for x1X-gtB
strategy A -gt B B -gt C
Object graph
Traversal graph
A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
c3C
Used for token set and currently active object
25Short-cut
Active strategy graph edges A-gtB B-gtC for
B-gtx2X
strategy A -gt B B -gt C
Object graph
Traversal graph
A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
c3C
Used for token set and currently active object
26Short-cut
Active strategy graph edges B-gtC for x2X-gtc1C
strategy A -gt B B -gt C
Object graph
Traversal graph
A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
c3C
Used for token set and currently active object
27Short-cut
strategy A -gt B B -gt C
Object graph
Traversal graph
A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
c3C
Used for token set and currently active object
28Short-cut
Active strategy graph edges A-gtB for A-gtx1X
strategy A -gt B B -gt C
Object graph
Traversal graph
A
After going back to x1X
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
Used for token set and currently active object
c3C
29Short-cut
Active strategy graph edges none for A
strategy A -gt B B -gt C
Object graph
Traversal graph
A
After going back to A
A
start set
x1X
B
x
0..1
b
b
x2X
X
X
B
x
x
c1C
c
b
B
c2C
finish set
C
Used for token set and currently active object
c3C
30SEdges
- SEdges Vector(SEdge).
- SEdge
- ltsourceNamegt String
- lttargetNamegt String.
31Class Dictionary
- Person Brothers Sisters Status.
- Status Single Married.
- Single .
- Married ltmarriedTogt Person.
- Brothers Person.
- Sisters Person.
32Strategy
- from Person bypassing Person
- through Married
- bypassing Person
- through Person
- bypassing Person
- through Brothers, Sisters
- bypassing Person
- to Person
33Strategy and Traversal States
- Person -gt Married bypassing Person
- Married -gt Person bypassing Person
- Person -gt Brothers bypassing Person
- Person -gt Sisters bypassing Person
- Brothers -gt Person bypassing Person
- Sisters -gt Person bypassing Person
- void before (Person h)
- if (previousSEdges()) print(h.getName())
else - if (previousSEdges(Married-gtPerson))
- print(spouseh.getName()) else
- if (previousSEdges(Brothers-gtPerson))
- print(brother-in-lawh.getName())else
- if (previousSEdges(Sisters-gtPerson))
- print(sister-in-lawh.getName())
-
34Strategy and Traversal States
- Person -gt Married bypassing Person
- Married -gt Person bypassing Person
- Person -gt Brothers bypassing Person
- Person -gt Sisters bypassing Person
- Brothers -gt Person bypassing Person
- Sisters -gt Person bypassing Person
- void before (Person h)
- if (nextSEdges(Person-gtMarried))
print(h.getName()) else - if (nextSEdges(Person-gtBrothers,Sisters))
- print(spouseh.getName()) else
- if (previousSEdges(Brothers-gtPerson))
- print(brother-in-lawh.getName())else
- if (previousSEdges(Sisters-gtPerson))
- print(sister-in-lawh.getName())
-
35Programming with Strategies
- At a given point during the traversal a set of
strategy graph edges is active. The set of active
strategy graph edges changes as we move through
the object graph. When we are at a node in the
object graph, we can talk about the next and
previous set of strategy graph edges. - boolean nextSEdges(Strategy s)
- boolean nextSEdges(String str)
- boolean previousSEdges(Strategy s)
- boolean previousSEdges(String str)
- The meaning is is the set of strategy graph
edges contained in the strategy? - nextSEdges(Person-gtBrothers,Sisters)
- previousSEdges(Brothers-gtPerson)
36Programming with Strategies
- When we are at an edge in the object graph, we
can talk about the current set of strategy graph
edges. - boolean SEdges(Strategy s)
- boolean SEdges(String str)
- boolean SEdges(TraversalGraph tg)
- The meaning is is the set of strategy graph
edges contained in the strategy?
37Visitor Methods forStrategy Edges
- void sbefore(Source s, Target t) // strategy
- is executed before the traversal corresponding to
s-gtt is started. More precisely, if s-gtt is
currently not in the set of active strategy
edges, but it will be after the next traversal
step (going through an edge in the object graph),
the code of the sbefore method will be executed
before the next traversal step. - void safter(Source s, Target t) // strategy
- is executed after the traversal corresponding to
s-gtt is finished. More precisely, if s-gtt is
currently in the set of active strategy edges,
but it will not be after the next traversal step
(going through an edge in the object graph), the
code of the safter method will be executed before
the next traversal step.
38Be more general
- Allow code attachment not only to strategy edges
but to strategies.
39Visitor Methods forStrategies
- void sbefore(Strategy s) // strategy
- is executed before the traversal corresponding to
s is started. More precisely, if the current
object graph node is currently not in the scope
of s, but it will be after the next traversal
step (going through an edge in the object graph),
the code of the sbefore method will be executed
before the next traversal step. - void safter(Strategy s) // strategy
- is executed after the traversal corresponding to
s is finished. More precisely, if s the current
object graph node is currently in the scope of s,
but it will not be after the next traversal step
(going through an edge in the object graph), the
code of the safter method will be executed before
the next traversal step.
40Follow DJ rule
- Wherever a strategy is used, a string may be
used. - void sbefore(String str) // strategy
- void safter(String str) // strategy
41Programming with strategies
- check whether currently in scope of subtraversal
- // may be used in before, cbefore, rbefore,
sbefore - // sg a substrategy of current strategy
- if (SEdges(sg))
- // currently in traversal determined by
strategy sg - // tg a subgraph of current traversal graph
- if (SEdges(tg))
- // currently in traversal determined by
tg -
42Traversing an edge From C1 to C2
o2C2
o1C1
declared type of o2 is C3gtC2
e
go down e iff C1 lt.C C3 gt C2 when we go down
e, we execute the before method of all
cbefore methods that match the edge e in the
order the cbefore methods are listed in the
visitor.
43Similarity
- When we traverse an edge in the object graph,
several visitor methods (for edges) will be
executed. - the same visitor may have several cbefore methods
whose expansion includes the same object graph
edge. - When we traverse a node in the object graph,
several visitor methods (for nodes) may be
executed. - when an object graph node method is executed we
also execute the methods of the super classes.
44Executing cbefore_v(F f, W w)?
- Assuming that only one edge matches
- Object graph edge labeled v
- o1SubClass(F) -gt o2SubClass(W)
- Is F a superclass of class(o1)?
- Has F a construction edge labeled w to W?
- Execute method.
45Finding the edge methods
- Object graph edge labeled v
- o1class(o1) -gt o2class(o2)
- Is there any edge visitor cbefore_v for a
superclass of class(o1)? - Execute method.
- Use a hash table.
46before_v(F f, W w)?
- The second argument (W w) is uniquely determined
by the class graph and is only given so the
programmer can use the interface of the target
node. - Semantic check done by DJ Is W correct? Executed
each time the before method is called?
47Difference to DemeterJ for edge methods
- DJ only allows edge methods on construction edges
and repetition edges while DemeterJ also allows
edge methods on inheritance edges. - Motivation In DJ, we want the behavior of a
program to be invariant under flattening of the
class graph.
48Basket
Weight
Weight1
Fruit
Weight2
Weight1
Orange
Apple
B
Orange
49The following needs to be updated.
50Cycle checking example
- Growth plan consists of two steps
- Depth-first traversal visitor
- Cycle checking visitor
51DFS tree
1
6
2
3
7
4
5
52Visitors for graph algorithms
- StrategyType1
- Graph -gt Adjacency
- Adjacency -gt intermedVertex
- Vertex -gt Adjacency
53Visitors for graph algorithms
- GenericDFT
- (StrategyType1 s)
- s.intermed
- change (_at_
this.doSomething() - next() _at_)
54Visitors for graph algorithms
- void doSomething()
- //s.intermediate
- s.target
- boolean mark
- init (_at_ mark false _at_)
- change (_at_ if (!mark)
- marktrue next() _at_)
-
55Visitors for graph algorithms
- GenericCycleCheck
- Stack stack
- init (_at_ stacknew Stack() _at_)
- s.target
- change (_at_
- if (stack.include(this)
- print(cycle found)
- else stack.push(this)
- next() stack.pop() _at_)
- modifies GenericDFT
56Print vertices
- GenericPrintingDFT extends GenericDFT
- s.interm
- doSomething() this.print()
-
57Visitors for graph algorithms
- s1
- Graph -gt Adjacency
- Adjacency -gt intermedVertex
- through -gt,neighbors,
- Vertex -gt Adjacency
- through lt- ,source,
58Use
- s1 // previous view graph
- Graph
- dft() is GenericDFT(s1)
- dftPrint() is GenericPrintingDFT(s1)
- cycleCheck() is GenericCycleCheck(s1)
59Finding connected components
2
3
1
2
3
1
1
3 connected components
60Using strategy edge
- ConnectivityVisitor
- int compNumber
- init (_at_ compNumber0 _at_)
- s.source
- change (_at_ next() print(compNumber)
61Using strategy edge
- ConnectivityVisitor
- s.source-gts.target
- s.target.newConnComp()
- s.target
- newConnComp() compNumber1
- modifies GenericDFT
62Components of AP
- class graphs (C)
- strategies (S)
- structure-shy functionality (F)
- Main issue how do we specify and compose C, S
and F, to maximize reuse of any of them when the
others change.
63Components of AP
C
S
Each component should hard-code as few
assumptions as possible on the concrete form of
the others.
Should not refer to each other directly
F
64Components of AP
C
S
mixed connections S-gtC C-gtF
Clt-gtC Flt-gtF
F
65Composition of visitors, strategies and class
graphs
Generic visitors
Strategy types
gv1 gv2
st1
st1
st1
s1
Class graphs
s1 instantiation of st1 for CG1
gv1
CG1
CG2
gv2(gv1)(s1 CG1)
s1
gv2
instantiated behavior
66Component coupling in Demeter/Java
- C-F coupling
- class dictionaries contain visitor classes
- visitor classes refer to class dictionaries
- Problem
- change of cd necessary for change in visitor
- visitors not reusable
67Decoupling of C and F
- use generic visitors parameterized by strategy
objects, use generic name change. - change abstractly denotes all traversing methods
over different class graphs. How the visitor
participates is expressed in code associated with
change.
68Component coupling in Demeter/Java
- C-S coupling
- strategies refer to task-important classes also
used in class dictionaries - strategies are expressed in terms of
implementation class dictionaries! That is a
problem
69Improvements for the C-S coupling
- Use strategy types. In an instantiated program we
have strategies as objects. - Strategies are instantiated from strategy types.
70Component coupling in Demeter/Java
- F-F coupling
- visitor classes refer to methods defined in other
visitor classes - visitor classes refer to methods such as
get-capacity. - Problem
- visitor classes directly refer to each other
(less reusability)
71Improvements for F-F coupling
- parameterizing generic visitors with method
valued variables - counting, summing, collecting etc.
- equip generic visitors with input and return
ports.
72Structure of a generic visitor
genericModVisitor(Strategy s, Method m1,,mk)
//variables global for traversal init()
return() start() final() s.source
//variables that temp. extend host object
init() change() host.m1()
next.return next() host.localMethod1()
localMethod1()(_at_ _at_) // end of visitor
73next
- next.return
- return method in next visitor is invoked
- next visitor is bound by modifies statement
- next()
- invokes the next implementation for the method
denoted by change (either next visiting task
attached to traversal denoted by change or the
remainder of the traversal)
74Composition of visitors, strategies and class
graphs
Generic visitors
Strategy types
gv1 gv2
st1
st1
st1
s1
Class graphs
s1 instantiation of ST1 for CG1
gv1
CG1
CG2
gv2(gv1)(s1 CG1)
s1
gv2
instantiated behavior
75Component coupling in Demeter/Java
- Coupling between components is pretty low (thanks
to strategies) but can be improved further. - Tension between
- convenience for programmer
- having to define many name mappings can be
perceived as inconvenient - reduced coupling between components
76Improvements
- Parameterize adaptive programs (S,F compositions)
with class graphs. - Refer to class-valued and relation-valued
variables when programs are written. - When programs are used with a class graph,
specify mapping of variables to specific class
graph elements.
77Components of AP
C1
C2
S
C interface
Each component should hard-code as few
assumptions as possible on the concrete form of
the others.
Should not refer to each other directly
F
78Improvements
- Parameterize visitor classes with strategies to
reduce S-F coupling. - Refer to class-valued and relation-valued
variables when visitors are written. Also refer
to parts of strategy s s.source, s.target
(class-valued variables parameterized by
strategy). - Define strategy kinds and write visitors in terms
of those.
79Improvements
- Strategy kind
- from Begin via Middle to End
- Strategy
- from A via B via C to D
- Mapping
- from Begin via Middle to End
- from A via B via C to D
80Components of AP
C1
C2
S1
C interface
S interface
Should not refer to each other directly
F
S2
81Reduce coupling between visitors
- Visitor has a signature
- provided
- required