HTML and CSS Reference
In-Depth Information
2.2.4 Step 4: Refactor to Remove Duplication
The last phase is the most important one in the interest of writing clean code. When
enough code has been written to pass all the tests, it's time to review the work so far
and make necessary adjustments to remove duplication and improve design. There
is only one rule to obey during this phase: tests should stay green. Some good advice
when refactoring code is to never perform more than one operation at a time, and
make sure that the tests stay green between each operation. Remember, refactoring
is changing the implementation while maintaining the same interface, so there is no
need to fail tests at this point (unless we make mistakes, of course, in which case
tests are especially valuable).
Duplication can occur in any number of places. The most obvious place to
look is in the production code. Often, duplication is what helps us generalize from
hard-coded solutions. If we start an implementation by faking it and hard-coding a
response, the natural next step is to add another test, with different input, that fails
in the face of the hard-coded response. If doing so does not immediately prompt
us to generalize the solution, adding another hard-coded response will make the
duplication obvious. The hard-coded responses may provide enough of a pattern
to generalize it and extract a real solution.
Duplication can also appear inside tests, especially in the setup of the required
objects to carry out the test, or faking its dependencies. Duplication is no more
attractive in tests than it is in production code, and it represents a too tight coupling
to the system under test. If the tests and the system are too tightly coupled, we
can extract helper methods or perform other refactorings as necessary to keep
duplication away. Setup and teardown methods can help centralize object creation
and destruction. Tests are code, too, and need maintenance as well. Make sure
maintaining them is as cheap and enjoyable as possible.
Sometimes a design can be improved by refactoring the interface itself. Doing
so will often require bigger changes, both in production and test code, and running
the tests between each step is of utmost importance. As long as duplication is dealt
with swiftly throughout the process, changing interfaces should not cause too much
of a domino effect in either your code or tests.
We should never leave the refactoring phase with failing tests. If we cannot
accomplish a refactoring without adding more code to support it (i.e., we want to
split a method in two, but the current solution does not completely overlap the
functionality of both the two new methods), we should consider putting it off until
we have run through enough iterations to support the required functionality, and
then refactor.
Search WWH ::

Custom Search