necessary library files as compressed jar files. The
numerous searches available in the tool have various
input configurations that can affect the execution of
the search. The refactorings and metrics used can also
be specified. As such, the tool can be configured in a
number of different ways to specify the particular task
that you want to run. If desired, multiple tasks can be
set to run one after the other.
A previous study (Mohan et al. 2016) used the A-
CMA (Koc et al. 2012) tool to experiment with
different metric functions but that work was not
extended to produce source code as an output
(likewise, TrueRefactor (Griffith et al. 2011) only
modifies UML and Ouni, Kessentini, Sahraoui and
Boukadoum’s (Ouni, Kessentini, Sahraoui and
Boukadoum 2013) approach only generates proposed
lists of refactorings). MultiRefactor (Mohan and
Greer 2017) was developed in order to be a fully-
automated search-based refactoring tool that
produces compilable, usable source code. As well as
the Java code artifacts, the tool will produce an output
file that gives information on the execution of the task
including data about the parameters of the search
executed, the metric values at the beginning and end
of the search, and details about each refactoring
applied. The metric configurations can be modified to
include different weights and the direction of
improvement of the metrics can be changed
depending on the desired outcome.
MultiRefactor contains seven different search
options for automated maintenance, with three
distinct metaheuristic search techniques available.
For each search type there is a selection of
configurable properties to determine how the search
will run. The refactorings used in the tool are mostly
based on Fowler’s list (Fowler 1999), consisting of 26
field-level, method-level and class-level refactorings,
and are listed below.
Field Level Refactorings: Increase/Decrease
Field Visibility, Make Field Final/Non Final, Make
Field Static/Non Static, Move Field Down/Up,
Remove Field.
Method Level Refactorings: Increase/Decrease
Method Visibility, Make Method Final/Non Final,
Make Method Static/Non Static, Remove Method.
Class Level Refactorings: Make Class Final/Non
Final, Make Class Abstract/Concrete, Extract
Subclass/Collapse Hierarchy, Remove
Class/Interface.
The refactorings used will be checked for
semantic coherence as a part of the search, and will
be applied automatically, ensuring the process is fully
automated. A number of the metrics available in the
tool are adapted from the list of the metrics in the
QMOOD (Bansiya and Davis 2002) and CK/MOOSE
(Chidamber and Kemerer 1994) metrics suites. The
23 metrics currently available in the tool are listed
below.
QMOOD Based: Class Design Size, Number Of
Hierarchies, Average Number Of Ancestors, Data
Access Metric, Direct Class Coupling, Cohesion
Among Methods, Aggregation, Functional
Abstraction, Number Of Polymorphic Methods,
Class Interface Size, Number Of Methods.
CK Based: Weighted Methods Per Class,
Number Of Children.
Others: Abstractness, Abstract Ratio, Static
Ratio, Final Ratio, Constant Ratio, Inner Class Ratio,
Referenced Methods Ratio, Visibility Ratio, Lines Of
Code, Number Of Files.
In order to implement the element recentness
objective, extra information about the refactorings is
stored in the refactoring sequence object used to
represent a refactoring solution. For each solution, a
hash table is used to store a list of affected elements
in the solution and to attach to each a value that
represents the number of times that particular element
is refactored in the solution. During each refactoring,
an element, considered to be most relevant to that
refactoring, is chosen and the element name is stored.
After the refactoring has executed, the hash table is
inspected. If the element name already exists as a key
in the hash table, the value corresponding to that key
is incremented to represent another refactoring being
applied to that element in the solution. Otherwise, the
element name is added to the table and the
corresponding value is set to 1. After the solution has
been created, the hash table will have a list of all the
elements affected and the number of times for each.
This information is used to construct the element
recentness score for the related solution.
To improve the performance of the tool, the
recentness scores are stored for each element as the
search progresses in another hash table. This allows
the tool to avoid the need to calculate the element
recentness scores for each applicable element in the
current solution at the beginning of the search task.
Instead, the scores are calculated as the objective is
calculated, for each element it comes across. If the
element hasn’t previously been encountered in the
search, its element recentness value will be calculated
and stored in the hash table. Otherwise, the value will
be found by looking for it in the table. This eliminates
the need to calculate redundant element recentness
values for elements that are not refactored in the
search and spreads the calculations throughout the
search in place of finding all the values in the
beginning.
Automated Refactoring of Software using Version History and a Code Element Recentness Measure
457