Chapter 4. Refactoring

 

This chapter covers

  • Methods for maintaining discipline when refactoring
  • Common smells found in legacy code, and refactoring techniques for removing them
  • Using automated tests to support refactoring

In this chapter we’ll look at your most important weapon in the fight against legacy, namely refactoring. I’ll introduce some general tips for effective refactoring, as well as a few specific refactorings that I often use in real-world code. We’ll also look at techniques for writing tests for legacy code, which is vital if you want assurance that your refactoring work hasn’t broken anything.

4.1. Disciplined refactoring

Before we start looking at specific refactoring techniques, I want to talk about the importance of discipline when refactoring code. When performed correctly, refactoring should be perfectly safe. You can refactor all day long without fear of introducing any bugs. But if you’re not careful, what started out as a simple refactoring can rapidly spiral out of control, and before you know it you’ve edited half the files in the project, and you’re staring at an IDE full of red crosses. At this point you have to make a heart-wrenching decision: should you give up and revert half a day’s work, or keep going and try to get the project back into a compiling state? Even if you can reach the other side, you have no guarantee that the software still works as it’s supposed to.

4.2. Common legacy code traits and refactorings

4.3. Testing legacy code

4.4. Summary