Refactoring is the art of safely improving the design of existing code. This has a few implications:
Refactoring does not include just any changes in a system. Changes that represent design improvements or add new functionality are not all considered to be refactoring. While refactoring can be part of the process used to create new code, it's not the part that adds new features. For example, Extreme Programming , or XP, (described in Kent Beck's Extreme Programming Explained: Embrace Change ) uses test-driven development, which consists of writing a test, then writing new code to introduce new features, and, finally, refactoring to improve the design.
Refactoring is not rewriting from scratch. While there are times when it's better to start fresh, refactoring changes the balance point, making it possible to improve code rather than take the risk of rewriting it. Sven Gorts points out (private communication) that refactoring preserves the knowledge embedded in the existing code.
Refactoring is not just any restructuring intended to improve code. What distinguishes our definition from this is the idea that refactorings strive to be safe transformations. Even big refactorings that change large amounts of code are divided into smaller, safe refactorings. (In the best case, refactorings are so well defined that they can be automated.) We won't regard a change as refactoring if it leaves the code not working (that is, not passing its tests) for longer than a working session.
Refactoring changes the balance point between up-front design and emergent design. Up-front design is design done in advance of implementation; emergent design is design intertwined with implementation. The trade-off between up-front and emergent design hinges on how well we can anticipate problems or assess them in code, and whether it's easier to design and then translate to code or to code and then improve . Refactoring lowers the cost and risk of the emergent approach. (Reasonable people will disagree on where the line is, but I think all will agree that it shifts.)
Refactorings can be small or large. Many refactorings are small. Ideally, small refactorings are applied "mercilessly" enough that large refactorings are rarely needed. Even when applying large-scale refactorings, the approach is not no new features for six months while we refactor , but rather, refactor as we go, and keep the system running at all times .