32. Practical Refactoring-Based Framework Upgrade with Comeback!

8 downloads 15 Views 1MB Size Report
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