Page 268 -
P. 268
9.3 Software maintenance 251
Although reengineering and refactoring are both intended to make software easier
to understand and change, they are not the same thing. Reengineering takes place
after a system has been maintained for some time and maintenance costs are increas-
ing. You use automated tools to process and reengineer a legacy system to create a
new system that is more maintainable. Refactoring is a continuous process of
improvement throughout the development and evolution process. It is intended to
avoid the structure and code degradation that increases the costs and difficulties of
maintaining a system.
Refactoring is an inherent part of agile methods such as extreme programming
because these methods are based around change. Program quality is therefore liable to
degrade quickly so agile developers frequently refactor their programs to avoid this
degradation. The emphasis on regression testing in agile methods lowers the risk of
introducing new errors through refactoring. Any errors that are introduced should be
detectable as previously successful tests should then fail. However, refactoring is not
dependent on other ‘agile activities’ and can be used with any approach to development.
Fowler et al. (1999) suggest that there are stereotypical situations (he calls them
‘bad smells’) in which the code of a program can be improved. Examples of bad
smells that can be improved through refactoring include:
1. Duplicate code The same of very similar code may be included at different
places in a program. This can be removed and implemented as a single method
or function that is called as required.
2. Long methods If a method is too long, it should be redesigned as a number of
shorter methods.
3. Switch (case) statements These often involve duplication, where the switch
depends on the type of some value. The switch statements may be scattered
around a program. In object-oriented languages, you can often use polymor-
phism to achieve the same thing.
4. Data clumping Data clumps occur when the same group of data items (fields in
classes, parameters in methods) reoccur in several places in a program. These
can often be replaced with an object encapsulating all of the data.
5. Speculative generality This occurs when developers include generality in a
program in case it is required in future. This can often simply be removed.
Fowler, in his book and website, also suggests some primitive refactoring trans-
formations that can be used singly or together to deal with the bad smells. Examples
of these transformations include Extract method, where you remove duplication and
create a new method; Consolidate conditional expression, where you replace a
sequence of tests with a single test; and Pull up method, where you replace similar
methods in subclasses with a single method in a super class. Interactive development
environments, such as Eclipse, include refactoring support in their editors. This
makes it easier to find dependent parts of a program that have to be changed to
implement the refactoring.