Refactoring
Martin Fowler · 2018
Changing the structure of code without changing its behaviour, in small, safe, tested steps.
What it’s about
The second edition of Martin Fowler’s classic, rewritten with JavaScript examples. It defines refactoring precisely (changing the internal structure of code without changing its observable behaviour), explains when and why to do it, introduces code smells as the cues, and then gives a catalogue of named refactorings, each a small mechanical step you can do safely with tests underneath.
What I learned
Refactoring is small steps, not a rewrite. Each step is tiny and keeps the code working. String enough of them together and you can reshape a module completely without ever having a broken build.
Tests make it safe. Without tests you’re not refactoring, you’re editing and hoping. The tests are what let you move quickly.
Smells tell you where to start. Long functions, duplicated code, feature envy, data clumps. Naming the smell turns a vague “this is messy” into a specific next move.
Make the change easy, then make the easy change. That’s Kent Beck’s line, but it’s the spirit of the whole book. When a feature is hard to add, first refactor until it’s easy, then add it.
What I applied
This is the root of how I approach migrations, and I can point to it working:
- At Accedo I refactored a TV app’s video player from class components to function components and hooks. The move surfaced subtle changes in the order of state updates (and some dead code), which tests then pinned down. That’s the book’s point exactly: the tests caught what the refactor changed by accident (Smart TV Apps on Low-End Devices).
- At Sky, the TypeScript clean-up was refactoring at codebase scale: many small, non-functional merge requests, each easy to review and roll back, ending with the compiler enforcing types in the build (Driving a TypeScript Codebase to Zero Errors).
- When we replaced a commercial graph library with our own, we kept the public API close to the old one so screens could move across one at a time (Building a Graph Component Library).
It’s also how I think about training: add a little load, consolidate, repeat (Progressive Overload and Incremental Migration).
Where it connects
Progressive Overload and Incremental Migration · TDD as a Feedback Loop · Driving a TypeScript Codebase to Zero Errors · Clean Code · Practical Object-Oriented Design in Ruby
One line I keep coming back to
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
↩ Mentioned in (3)
Twenty-odd books across code, platforms, teams, trading and science fiction turn out to make the same five arguments. Here's the thread that connects them.
book · Robert C. Martin
Clean CodeReadable code as a professional responsibility: naming, small functions and leaving code better than you found it.
book · Sandi Metz
Practical Object-Oriented Design in RubyDesign as the art of keeping code easy to change, through small objects, clear messages and managed dependencies.