1 formalising behaviour-preserving object-oriented program transformations tom mens(...
TRANSCRIPT
1
FormalisingBehaviour-Preserving
Object-OrientedProgram Transformations
FormalisingBehaviour-Preserving
Object-OrientedProgram Transformations
Tom Mens ([email protected])Postdoctoral Fellow – Fund for Scientific Research (Flanders)
Vrije Universiteit Brussel, Belgium
in collaboration with
Serge Demeyer Dirk JanssensUniversiteit Antwerpen, Belgium
2ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
What is refactoring?What is refactoring?
Refactorings are software transformations that restructure an object-oriented application while preserving its behaviour.
According to Fowler (1999), refactoring improves the design of software makes software easier to understand helps you find bugs helps you program faster
Promising application area for graph rewriting
3ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
GoalGoal
Improve tool support for refactoring object-oriented software … more scalable (e.g., composite refactorings) more language independent guarantee behaviour preservation up to a certain degree
… by providing a formal model in terms of graph rewriting intuitive description of transformation of complex graph-like structures theoretical results help in the analysis of such structures
Show feasibility / limitations of graph rewriting for this purpose
4ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
workstation 1
fileserver 1
workstation 2printer 1
workstation 3
1. originate(p)
2. send(p)
3. accept(p)
4. send(p)
5. accept(p)
6. send(p)7. accept(p)
8.print(p)
Feasibility study: LAN simulationFeasibility study: LAN simulation
See special session on case studies,Saturday, October 12, 16:30
6ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Java source codeJava source code
public class Node { public String name; public Node nextNode; public void accept(Packet p) { this.send(p); } protected void send(Packet p) { System.out.println( name + "sends to" + nextNode.name); nextNode.accept(p); } }
public class Packet { public String contents; public Node originator; public Node addressee; }
public class Printserver extends Node { public void print(Packet p) { System.out.println(p.contents); } public void accept(Packet p) { if(p.addressee == this) this.print(p); else super.accept(p); } }
public class Workstation extends Node { public void originate(Packet p) { p.originator = this; this.send(p); } public void accept(Packet p) { if(p.originator == this) System.err.println("no destination"); else super.accept(p); } }
7ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Two selected refactoringsTwo selected refactorings
Encapsulate Field encapsulate public variables by making them private and providing
accessor methods Examples
EncapsulateField(name,String getName(),setName(String))EncapsulateField(nextNode,Node getNextNode(),setNextNode(Node))
Preconditions accessor method signatures should not exist in inheritance chain
Pull up method move similar methods in subclasses to common superclass Preconditions
method to be pulled up should not refer to variables defined in subclass, and its signature should not exist in superclass
8ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Refactoring – Encapsulate FieldRefactoring – Encapsulate Field
public class Node { private String name; private Node nextNode; public String getName() { return this.name; } public void setName(String s) { this.name = s; } public Node getNextNode() { return this.nextNode; } public void setNextNode(Node n) { this.nextNode = n; } public void accept(Packet p) { this.send(p); } protected void send(Packet p) { System.out.println( this.getName() + "sends to" + this.getNextNode().getName()); this.getNextNode().accept(p); } }
public class Node { public String name; public Node nextNode; public void accept(Packet p) { this.send(p); } protected void send(Packet p) { System.out.println( name + "sends to" + nextNode.name); nextNode.accept(p); } }
9ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Behaviour preservationBehaviour preservation
Only look at static structure of a program
Many different kinds of preservation Access preserving
each method body (transitively) accesses at least the same variables as it did before the refactoring
Update preserving each method body (transitively) performs at least the same variable
updates as it did before the refactoring Call preserving
each method body (transitively) performs at least the same method calls as it did before the refactoring
10ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph notation – structureGraph notation – structure
program structure
contents V originator V addressee V
Packet C
iNode C
name V nextNode V (send) B (accept) B
p
PrintServer C
(accept) B (print) B
Workstation C
(accept) B(originate) B
i
String C
send S P
paccept S P
poriginate S P
pprint S P
t
l
l
l
l
tprintln S Pp t
tt
tt
11ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph notation – behaviourGraph notation – behaviour
behaviour of class Node
l
name V nextNode V (send) B (accept) B
paccept S Pprintln S Pp
E
e
d
pE
ea
E
psend S P
d
pE
e
d
pEE
a
d
+ S
Ep
a
E
at
E
aE
a
Node CString C
t
l
12ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Node type setNode type set
Type Description Examples
C Class Node, Workstation, PrintServer, Packet
B method Body System.out.println(p.contents)
V Variable name, nextNode, contents, originator
S method Signature in lookup table accept, send, print
P formal Parameter of a message p
E (sub)Expression in method body p.contents
13ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Edge type setEdge type set
Type Description Examples
l: S B dynamic method lookup
i: C C inheritance class PrintServer extends Node
m: V|B C class membership
t: P|V|S C type send(Packet p), String getName()
p: S P formal parameter send(Packet p)
p: E E actual parameter System.out.println(nextNode.name)
e: B E expression in method body
•: E E cascaded expression nextNode.accept(p)
d: E S dynamic method call this.send(p)
a : E P|V access of parameter of variable
p.originator
14ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Well-formedness contraintsWell-formedness contraints
Use type graph
E aP
S
p
Bl
C
m
V
m t
a u
t
e .p
i
t d
15ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Well-formedness constraintsWell-formedness constraints
Use forbidden subgraphs WF-1: a variable with the same name cannot be defined twice in
the same inheritance hierarchy WF-2: a method with the same signature cannot be implemented
twice in the same class WF-3: a method cannot refer to variables in descendant classes
WF-3
B
V
C m
m i +
?* {a|u}
C
C
i*
aVm
aVm
WF-1
1
2
B
B
l aS
aS
C
m
m l
WF-2
1
2
16ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph production EncapsulateFieldGraph production EncapsulateField
EncapsulateField(var,accessor,updater) parameterised production embedding mechanism takes context into account
var V1
l l
B Bvar Va e
updater S accessor S
Ee u
p
Pp
1
a
E
E2 3
4 57
6
8
9
incoming edges outgoing edges
(u,1) (d,2) (m,1) (m,1), (m,4), (m,5)
(a,1) (d,3) (t,1) (t,1), (t,3), (t,6)
17ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph production EncapsulateFieldGraph production EncapsulateField
Application of the production in the context ofthe LAN simulation EncapsulateField(name,getName,setName)
name V
a a
Node CString C
t
m
EE
Node C
d
String C
tt
l l
B Bname Va
e
setName S getName S
Ee u
p
Pp a
E
E
EEd
t
m
18ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Access preservingAccess preserving
B V?*a
var VEE accessor S B
1
d l aevar V
1
a
853
B?*
EB?*
Use graph expression
EncapsulateField preserves behaviour access preserving: all attribute nodes can still be accessed via a
transitive closure
19ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Update preservingUpdate preserving
Use graph expression
EncapsulateField preserves behaviour update preserving: all attribute nodes can still be updated via a
transitive closure
var VEE updater S B
1
d l uevar V
1
u
B V?*u
742
B?*
EB?*
20ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph production PullUpMethodGraph production PullUpMethod
PullUpMethod(parent,child,name) has an effect on all subclasses controlled graph rewriting needed
name S4
child C
B
m
parent C1
2
3 l
i
name S4
child C
B
m
parent C1
2
3 l
i
P1P2
name S4
C
B
m
parent C1
2
l
i
3
name S4
C
B
m
parent C1
2
i
3
21ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Graph production PullUpMethodGraph production PullUpMethod
d P1 P2
repeat
d
succeed
dfail
precondition
22ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Call preservingCall preserving
Use graph expression
PullUpMethod preserves behaviour call preserving:
B S?*d
Bl
B Cm
name S lparent C
i4 3 1B C
mname S lparent C
i4 3 1
23ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Satisfying preconditionsSatisfying preconditions
All refactorings must satisfy well-formedness conditions WF-1, WF-2, WF-3
Some refactorings require additional constraints E.g. EncapsulateField may not introduce accessor/updater method
if their signatures are defined in the inheritance chain (RC1)
Use negative application preconditionsto fulfill these constraints E.g., for EncapsulateField
var Vm1 m l
updater SC BCi*
var Vm1 m l
accessor SC BCi*
var Vm1 m l
updater SC BCi*
var Vm1 m l
accessor SC BCi*
24ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Tool supportTool support
Java to graph parser different graph formats (…GXL…)
Specified refactorings in Fujaba
Javasourcecode
Parser GraphVisualisation
tool
Javasourcecode
Fujaba Refactoringtransfos
Checkpreservation
refactor
25ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Lessons learnedLessons learned
graph rewriting suitable for specifying effect of refactorings language-independent natural and precise way to specify transformations behaviour preservation can be formally verified
better integration of existing graph techniques needed well-formedness constraints (type graphs, forbidden subgraphs)
suitable graph constraint language? infinite sets of productions (parameterisation and embedding) restricting applicability (negative preconditions and controlled rewriting)
need to manipulate complex graph structures e.g. push down method
26ICGT, 10 October 2002, Barcelona © Tom Mens, Vrije Universiteit Brussel
Future workFuture work
many future research issues, to be addressed in research project “A Formal Foundation for Software Refactoring”
starting on 1 January 2003 financed by Fund for Scientific Research – Flanders (Belgium)
more validation more refactorings more case studies more kinds of behaviour preservation
time preservation (for time-critical systems) memory and power preservation (for embedded systems)
further work on formalism arbitrary evolution steps language independence and scalability
refactoring in a dynamic evolution context?