Towards Improving Interface Modularity in Legacy Java Software through Automated Refactoring Ra Khatchadourian, Olivia Moore Computer Systems Technology, New York City College of Technology City University of New York, USA Hidehiko Masuhara Mathematical and Computing Science, Tokyo Institute of Technology, Japan International Workshop on Language Modularity 2016 (LaMOD'16) at the International Conference on Modularity (MODULARITY'16) Málaga, Spain March 15, 2016
32
Embed
Towards Improving Interface Modularity in Legacy Java Software Through Automated Refactoring
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Towards Improving InterfaceModularity in Legacy Java
Software through AutomatedRefactoring
Ra� Khatchadourian, Olivia MooreComputer Systems Technology, New York City College of Technology
City University of New York, USA
Hidehiko MasuharaMathematical and Computing Science, Tokyo Institute of Technology,
Japan
International Workshop on Language Modularity 2016 (LaMOD'16) atthe International Conference on Modularity (MODULARITY'16)
Málaga, Spain
March 15, 2016
New Features in Java 8
Largest change was in ~2005 with Java 5.10 years later, Java 8 is packed with new features.Java 9 is on the horizon (Project Jigsaw, i.e., "modular Java", etc.)Our focus is Java 8 enhanced interfaces that allow default methods.
Java InterfacesA list of public method declarations (no bodies) that
concrete implementers (classes) must de�ne.
The Java Interface Type
Cannot be instantiated (abstract).Cannot contain instance �elds.Can extend other interfaces.Can contain public static �elds and methods (new in Java 8).
Multiple classes can implement an interface and aninterface can be implemented by multiple classes.
ExampleList contains declarations of methods common to all lists.
interface List<E> { //... /** * Removes all of the elements from this list (optional operation). * @throws UnsupportedOperationException if the clear operation * is not supported by this list. */ void clear(); //... }
MyList is a particular kind of list.
class MyList<E> implements List<E> { //... @Override public void clear() { // not supported. throw new UnsupportedOperationException(); } //... }
A List can refer to MyList instances in clients.
List<E> list = new MyList<>();
The Skeletal ImplementationPattern
Default behavior for interface methods.
ProblemInterface implementers may share common functionality.Some interface methods may be optional (like List.clear()).
Skeletal ImplementationsProvide separate abstract class as a partial interface implementation[Bloch'08].Implementers extend the skeletal implementation instead.Inherit "default" and/or partial interface method de�ntions.Makes implementing the interface easier.
Exampleinterface List<E> { //... /** * Removes all of the elements from this list (optional operation). * @throws UnsupportedOperationException if the clear operation * is not supported by this list. */ void clear(); //... }
abstract class AbstractList<E> implements List<E> { //... @Override public void clear() { // not supported. throw new UnsupportedOperationException(); } //... }
class MyList<E> extends AbstractList<E> { //... // Inherits default implementation of clear(). }
IssuesFlexibility
Java has single class inheritance -> classes cannot extend classesother than the skeletal implementation (can use delegation instead[Bloch'08]).
EvolvabilityInterface modi�cations must be in sync with skeletalimplementions in separate classes.
ModularityNo syntatical path from the interface to its skeletal implementation.Developers wishing to implement an interface may need a globalanalysis to �nd corresponding skeletal implementers.
Default MethodsAdd default behaviors to interfaces
Default MethodsTraditionally, interfaces can't have method de�nitions (justdeclarations).Default methods supply default implementations of interfacemethods.By default, implementers will receive this implementation if they don'tprovide their own.
Examples
Example 1Basics
interface List<E> { //... default void clear() { throw new UnsupportedOperationException(); } } class MyList<E> implements List<E> { //... }
Why is this Complicated?Corresponds to converting and migrating a skeletal (instance) method
implementation to an interface.
From a class To an interfaceinstance method default method
Can we not simply use a "Pull Up Method" [Fowler'99] refactoring?
Not exactly. The inherent problem is that, unlikeclasses, interfaces may extend multiple interfaces. As
such, we now have a kind of multiple inheritanceproblem to deal with.
Some (perhaps) ObviousPreconditions
Source instance method must not access any instance �elds.Interfaces may not have instance �elds.
Can't currently have a default method in the target interface withthe same signature.Can't modify target method's visibility.
Some Obvious TasksMust replace the target method in the interface (add a body to it).Must add the default keyword.Must remove any @Override annotations (it's top-level now).If nothing left in abstract class, remove it?Need to deal with documentation.
Some Not-so-obviousPreconditions
Suppose we have the following situation:
interface I { void m(); } interface J { void m(); } abstract class A implements I, J { @Override void m() {...} }
Here, A provides a partial implementation of I.m(), which also happensto be declared as part of interface J.
Some Not-so-obviousPreconditions
Now, we convert and migrate A.m() to a default method of I:
interface I { default void m() {..} //was void m(); } interface J { void m(); //stays the same. } abstract class A implements I, J { //now empty, was: void m() {...} }
We now have a compile-time error in A because A needs to declarewhich m() it inherits.In general, inheritance hierarchies may be large and complicated.Other preconditions may also exist (work in progress).