CHAPTER 2 Writing Maintainable, Future-Friendly Code
One of the primary tasks of the code maintainer is to eliminate magic
from the codebase. As you work with the code, fixing bugs or adding new
functionality, make sure that you document what you do. Every time you
touch legacy code, seek to get a better understanding of what it’s doing.
When you make a discovery, write it down. Writing it down is as simple as
leaving a comment or two in the code so that the next person who looks at
it won’t have to wonder why something was done.
It’s best to leave a trail of comments such as this so that you slowly
start to build up a base of knowledge around how the code works. This
comes in handy not just for others, but for you if you find yourself work-
ing on this code again months or years down the line.
aDD TeSTS
Michael C. Feathers, author of Working Effectively with Legacy Code (Pearson,
2004), describes legacy code as any code that doesn’t have tests. In practice,
the pain of legacy code is often associated with a lack of tests, which is
why the code begins to seem like magic. Without anything documenting
expected behavior, either in the way of comments, formal documentation
or good tests, it’s very hard to feel confident when making changes to lega-
cy code. Once again, it’s unlikely that you’ll ever have enough time to stop
and write tests for all the legacy code at once. That doesn’t mean that you
should give up on tests altogether.
The approach for adding tests to legacy code is very similar to add-
ing comments in legacy code. Whenever you work with the code, make
it a point to add at least one test. If you’re fixing a bug, write a test that
reproduces the issue before attempting to fix it. This is called test-driven
development. You start by writing a test that fails (because of the bug) and
then write code that makes the test pass. After fixing the bug, you can add
comments to the code and check in the new test. That’s now one less part
of the code that seems to be magic.