OO
Refactoring and Design Patterns Research
I
teach an undergraduate course on Software Design,
and a good part of
that course deals with different forms of design patterns and
refactorings. Personally, I am unsatisfied with the
'practical' state of classical design patterns and existing tool
support. Eclipse, for instance, is awful IMO on the
refactorings that it offers (the JDTRE -- or JDT Refactoring Engine) is infested with bugs) and the lack
of support to script refactorings. I was tired of handwaiving
descriptions of design patterns and what specific refactorings
should do, but don't. I wanted to change the way OO refactorings
and classical design patterns are taught to students.
I
think of it this way: I was in college when students stopped
using slide rules and transitioned to hand-held calculators.
Back then, you performed one computation at a time.
I used an HP-45.
It was but a year or so afterwards that the first
programmable calculator appeared -- because people obviously wanted to
perform a series of well-defined computations repeatedly, and programs
were the way to go. Well, it has been known for 10-15 years
(see Kerievsky2006, Tokuda and
Batory1999) that
most, not all, classical design patterns in the Gang-of-Four
Text
can implemented as refactoring scripts -- a sequence, including loops,
of refactorings. Others have long noted before us that
scripting refactorings is an important step forward in IDE
capabilities, but nothing much has happened. Students and
programmers do not want to learn a domain-specific languages, program
transformation systems, and/or IDE development kits to write
refactoring scripts. Here's where I found teaching and
research come together nicely.
We
(Jongwook Kim, Danny Dig, and I) have been working on a new technology
to add refactoring scripts to IDEs, in particular Eclipse.
Our work is long-term, and below I describe our current (but
not future) work on the subject. R2 and R3 below are now integrated into my undergraduate Software Design and my graduate course on Automated Software Design.
- R2
-- Our idea was to use Java as a refactoring script language.
There is no need for a DSL or learning heavyweight tools.
R2 is a Java package whose classes are remininscent of
Java Reflection: objects that are exposed to users correspond
to packages, classes, methods, fields, etc. of an Eclipse project.
Methods of these objects are JDTRE refactorings and
operations that allow users to navigate among R2 objects -- such as
retrieve all methods of a given class; find the class of the current
method; what classes are in a given package, and so on. Our
work on R2 ("reflective refactoring") is described in:
Related
to this work is a never-ending list of bugs that we have found in the
Eclipse JTDRE. Why is this important? Well, if you execute
a script and 100s of bugs are introduced into your program (because
JTDRE refactorings are not trust-worthy), you're (a) not likely to use
scripting, (b) you can't use Eclipse JDTRE to manually introduce a
pattern because these same bugs would be introduced, and most likely
(c) you won't use Eclipse refactorings period if they're untrustworthy.
Here is our current list of bugs that we've found; as we discover
more, we post them here.
- R3
-- We discovered from our R2 work that Eclipse's JDTRE is unsuitable
for refactoring scripts: it is too slow and buggy to be useful.
Fixing JDTRE was not an option -- to improve performance
required a complete rethinking of how refactoring engines should be
implemented. Our work on R3 takes a novel approach to
implement refactorings (at least refactorings for design patterns --
but we know R3 is much more general) by NOT altering abstract syntax
trees (ASTs) as everyone does today. Rather, we create a
non-persistent main-memory database of R2-like objects, where classical
refactorings simply modify the tuples and containment relationships.
ASTs are never updated; consequently refactoring scripts run
lightning fast. We then pretty-print ASTs in a manner that
observes the changes to the database to produce source of refactored
project. We have several examples where R2 run times are 5
minutes, which R3 performs in mere seconds. On average, our
experiments show R3 runs about 10x faster than JDTRE. Our
work on R3 ("relative reflective refactoring") is described in:
- X15 or R4 --
This is the first refactoring engine for Java Software Product Lines
(SPL). Not only can users edit AND refactor an entire
Java-with-annotations codebase, they can also edit and refactor an
individual program (product) of an SPL, all without the problems of
backpropagation (which we explain in the second paper below that
backpropagation techniques do NOT work for refactoring). Not only
that, we inherit all the benefits of R3 -- X15 is only a few percent
slower than R3, which is 10x (and more) faster than Eclipse! And
to top it off, we do not need a special variability-aware Java compiler
-- we use the Eclipse (or any existing) Java compiler, and the codebase
for X15 is about 10K LOC Java. And further, X15 supports 34 different
primitive refactorings (the same as R3) and the scripts that run for R3
also run for X15. So X15 is also the first refactoring scripting
engine for Java SPLs, too!
- Jongwook Kim's PhD Thesis: Reflective and Relativistic Refactoring with Feature-Awareness, 2017.
- Priscila Angulo-Lopez's PhD Thesis: Semi-Automatic Program Partitioning, 2017
Coming Attractions!
- BttF (Back To The Future Tool) --
We are developing a theory and accompanying tools on how Java legacy
applications can be refactored into a composition of features. It
will leverage R4 and other existing product line analyses. Please see Priscila Angulo-Lopez's PhD thesis.
Other Refactoring Publications
All
our publications on refactorings can be found can be found here.