Comebacks: Refactoring Inverses on Adapters .... no comebacks for refactorings
implying this ... no white-box adaptation (accidental overriding possible);.
32. Practical Refactoring-Based Framework Upgrade with Comeback!
Ilie Şavga, Michael Rudolf, Sebastian Götz, Uwe Aßmann 20.10.2008 GPCE'08: Nashville, Tennessee
Restructuring a Sign Department of Computer Science, Technische Universität Dresden
John Thompson , hatter, makes and sells hats for ready money.
Benjamin Franklin, as cited in Kerievsky, 2004
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 2 of 24
Refactoring and Software Evolution Department of Computer Science, Technische Universität Dresden
"A large program that is used undergoes continuing change or becomes progressively less useful." Lehman and Belady, p. 250 Lehman's first law "As a large program is continuously changed, its complexity … increases unless work is done to maintain or reduce it." Lehman and Belady, p. 253 Lehman's second law "Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure."
Fowler et al., 1999, xvi
Behavior-preserving yet structural-improving
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Opdyke, 1992; Roberts, 1999
Slide 3 of 24
Software Frameworks and Plugins Department of Computer Science, Technische Universität Dresden
Framework Version 1 Node
A software framework is a software component that embodies a skeleton solution for a family of related software products and is instantiated by modules containing custom code (plugins).
String getName () void broadcast (String msg)
Johnson and Foote, 1998
instance-of
LAN void enter (Node node){ node. broadcast(node.getName() + " enters the network"); }
Plugin Version 1 TU Dresden, 20.10.2008
Examples inspired by Demeyer et al., 2005
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 4 of 24
Framework Refactoring Breaking a Plugin Department of Computer Science, Technische Universität Dresden
Framework Version 2 Framework Version 1 Node ExtractSubclass
Node
String getName ()
String getName () void broadcast (String msg)
Workstation void broadcast (String msg) instance-of
Refactorings comprise 75-97% of application-breaking API changes.
LAN void enter (Node node){ node. broadcast(node.getName() + " enters the network"); }
Dig and Johnson, 2005; Dagenais and Robillard, 2008; Schäfer et al., 2008; Şavga et al., 2008;
Plugin Version 1 TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 5 of 24
Refactoring-Driven Adaptation Department of Computer Science, Technische Universität Dresden
ExtractSubclass
Adapter is a well-known design pattern to bridge a software component mismatch.
Framework Version 2 generate
Node String getName ()
GoF, 1995;
delegate
Workstation Node instance-of
LAN void enter (Node node){ node. broadcast(node.getName() + " enters the network"); }
delegate
String getName () void broadcast (String msg)
Adapter Version 1
“The most structured way to deal with component evolution and upgrading, which is likely to result in new mismatches, arguably is by applying adaptation techniques.”
Plugin Version 1 TU Dresden, 20.10.2008
void broadcast (String msg)
Becker et al., 2004
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 6 of 24
Comebacks: Refactoring Inverses on Adapters Department of Computer Science, Technische Universität Dresden
Version 1
Version 2
Framework Evolution
r1
r2
r3
r4
Adaptation
c1 c2 c3 c4
Adapters
Plugins TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 7 of 24
Comebacks: Refactoring Inverses on Adapters Department of Computer Science, Technische Universität Dresden
Version 1
Version 2
Version 3
Evolution
Refactorings History
Framework
input
Adapter Generator generate
Adaptation Layers
Plugins TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 8 of 24
Adapter Design Pattern (Object Version) Department of Computer Science, Technische Universität Dresden
Adaptee specificRequest() adaptee
Target
Adapter request() { adapter.specificRequest(); }
request()
use
Client target.request(); GoF, 1995
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 9 of 24
Refined Adapter Design Pattern (Object Version) Department of Computer Science, Technische Universität Dresden
AdapteeImpl request()
Adaptee specificRequest() adaptee
Target
Adapter request() { adapter.specificRequest(); }
request()
use
Client target.request(); GoF, 1995
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 10 of 24
The Comeback! Black-Box Interface Adapter Department of Computer Science, Technische Universität Dresden
Framework Version 2
TokenPacket Node getCreator()
IPacket Node getCreator() adaptee
Adaptation Layer Version 1
IPacket Node whoCreated()
IPacketAdapter Node whoCreated()
use
Plugin Version 1
LAN packet.whoCreated();
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 11 of 24
The Comeback! White-Box Interface Adapter Department of Computer Science, Technische Universität Dresden
Framework Version 2
PrintServer
use
print (packet.getCreator());
IPacket Node getCreator()
Adaptation Layer Version 1
IPacket Node whoCreated()
adaptee
IPacketAdapter Node getCreator()
Plugin Version 1
LAN packet.whoCreated();
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 12 of 24
A White-Box Framework (Re-use by Inheritance) Department of Computer Science, Technische Universität Dresden
Framework Version 1
Node
PrintServer debug (Node n){ Log.write(n.getName()); }
use
String getName()
use
Plugin Version 1
LAN Node n = new SecureNode(); ... utils.debug(n);
TU Dresden, 20.10.2008
use
SecureNode //encryption info String getDescription()
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 13 of 24
Fragile Base Class Problem: Method Capture Department of Computer Science, Technische Universität Dresden
Framework Version 2
Node
PrintServer debug (Node n){ Log.write(n.getDescription()); }
use
String getName() String getDescription(){ this.getName(); }
use
Plugin Version 1
LAN Node n = new SecureNode(); ... utils.debug(n);
use
SecureNode //encryption info String getDescription()
Steyaert et al, 1996; Mikhajlov and Sekerinski , 1998
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 14 of 24
Method Capture Solved with Comback!White-Box Class Adapter Department of Computer Science, Technische Universität Dresden
Framework Version 2
PrintServer
call
Debug (Node n){ Log.write(n.getDescription()); }
Node String getName() String getDescription(){ this.getName(); }
Adaptation Layer Version 1
Node String getName(){ adapter.getName(); }
adaptee adaptee
NodeAdapter //run-time method dispatch
Plugin Version 1
SecureNode //encryption info String getDescription()
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 15 of 24
Exhaustive API Adaptation: Management of Adapters Department of Computer Science, Technische Universität Dresden
Call Framework -> Plugins
Call Plugins -> Framework
Framework
Adapter Cache
Adaptation Layers
Plugins TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 16 of 24
FrameworkPlugin Object Exchange Department of Computer Science, Technische Universität Dresden
Framework Version 1 public class PacketFactory{ private Hashmap packetHistory; public Packet createPacket(PacketType type, INode creator){ Packet pckt = new Packet(type); pckt.setCreator(creator); packetHistory.save(pckt); return pckt; } }
Plugin Version 1 SecureNode node = new SecureNode(); PacketType pt = PacketFactory.getEncryptedPacketType(); … Packet packet = PacketFactory.createPacket(pt,node);
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 17 of 24
Wrapping and Unwrapping of Parameter Objects in the Adaptation Layer Department of Computer Science, Technische Universität Dresden
New Framework public class PacketFactory{ private Hashmap packetHistory; public Packet createPacket(PacketType type, INode creator){ Packet pckt = new Packet(type); pckt.setCreator(creator); packetHistory.save(pckt); return pckt; } }
Adaptation Layer
unwrap
wrap
consult/update
adapter cache
Old Plugin SecureNode node = new SecureNode(); PacketType pt = TypeFactory.getEncryptedPacketType(); … Packet packet = PacketFactory.createPacket(pt,node);
TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 18 of 24
Tool Validation: the ComeBack! Department of Computer Science, Technische Universität Dresden
Refactoring Engines, Code Analyzers
Framework Binaries parsing
acquisition
Framework Fact Base
Refactoring History
Prolog Engine
ComeBack!
Comeback Library
Adapter Fact Base pretty printing
Adapter Layer
ComeBack! homepage: http://comeback.sf.net TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 19 of 24
Side-by-Side Plugin Execution Department of Computer Science, Technische Universität Dresden
Version 1
Version 2
Version 3
Evolution
Refactorings History
Framework
input
Adapter Generator generate
Application Adaptation Layers
Plugins TU Dresden, 20.10.2008
Ilie Şavga, Michael Rudolf, Sebastian Götz and Uwe Aßmann
Slide 20 of 24
Case Studies Department of Computer Science, Technische Universität Dresden SalesPoint; JHotDraw Java-based frameworks: SalesPoint and JHotDraw • application-driven refactoring detection • no backward compatibility concern but 85% • comebacks specified and executed, remaining changes adapted manually
Effectiveness: all refactorings adapted Performance: up to 6.5% overhead