Refactoring and
Patterns
On various projects, I've
observed
what and how
my colleagues and I refactor. While we use many of the refactorings
described in
Refactoring
[F], we
also find places where patterns help us improve our designs. At
such times, we refactor to or towards patterns, being careful not
to produce overly flexible or unnecessarily sophisticated
solutions.
When I explored the motivations for applying
pattern-directed refactorings, I found they are identical to the
general motivations for implementing low-level refactorings: to
reduce or remove duplication, to simplify what is complicated, and
to make code better at communicating its
intention
.
This motivation can easily be missed if you
study only a portion of a design pattern. For example, every
pattern in
Design Patterns
[DP]
includes a section known as the Intent. The authors of
Design Patterns
describe the Intent as
follows
: "A short statement that answers the following questions:
What does the design pattern do? What is its rationale and intent?
What particular design issues or problem does it address?" [DP, 6].
Despite this description, the Intent sections for many design
patterns only hint at the main problem the pattern
solves
. Instead,
more of the focus is put on what the pattern does. Here are two
examples.
Intent of Template
Method
Define the skeleton of an algorithm in an
operation, deferring some steps to subclasses. Template Method lets
subclasses redefine certain steps of an algorithm without changing
the algorithm's structure. [DP, 325]
Intent of
State
Allow an object to alter its behavior when its
internal state changes. The object will appear to change its class.
[DP, 315]
These Intent descriptions don't say that a
Template Method
helps reduce or
remove
duplicated
code in similar
methods
of subclasses in a
hierarchy or that the
State
pattern helps simplify complex conditional state-changing logic. If
programmers study all of the sections of a design pattern,
particularly the Applicability section, they'll learn about the
problems the pattern addresses.
However, when using the
Design Patterns
book during design, many
programmers,
myself
included, have read the Intent section of a
pattern to see whether the pattern could provide a good fit for a
given situation. This method of choosing a pattern doesn't work as
well as a method that helps you match a design problem to the
problems addressed by a pattern. Why? Because patterns exist to
solve problems, and learning whether they really can help in a
given situation involves understanding what problems they help
solve.
The refactoring literature tends to focus more
on specific design problems than the patterns literature does. If
you study the first page of a refactoring, you'll see the kind of
problem the refactoring helps solve. The catalog of
pattern-directed refactorings presented in this book, which is a
direct continuation of work started in
Refactoring
, is intended to help you see what
kinds of specific problems the patterns help solve.
While this book bridges the gap between patterns
and refactoring, the connection between the two was noted by the
authors of
Design Patterns
in the
conclusion to their great book:
Our design patterns capture many of the
structures that result from refactoring. . . . Design patterns thus
provide targets for your refactorings. [DP, 354]
Martin Fowler makes a similar observation near
the beginning of
Refactoring
:
There is a natural relation between patterns and
refactorings. Patterns are where you want to be; refactorings are
ways to get there from somewhere else. [F, 107]
|