Clean Code

What is Refactoring?

Refactoring is changing the structure of code without changing its behavior. You don't add features. You don't fix bugs. You improve the design so the cod...

14 Oct 2023

What is Refactoring?

Refactoring is changing the structure of code without changing its behavior. You don't add features. You don't fix bugs. You improve the design so the code is easier to understand and cheaper to modify.

That's the definition. Here's the reality.

Why refactoring is risky

Refactoring touches working code. Every change is a chance to break something. Done carelessly, it can set you back days.

Done systematically — with tests, small steps, and frequent commits — it's one of the most powerful techniques in software development.

The first step: tests

Before I refactor anything, I make sure there's a solid test suite covering the behavior I'm about to change. The tests are the safety net. Without them, I'm doing surgery blindfolded.

Before you start refactoring, make sure you have a solid suite of tests. These tests must be self-checking.

If the tests don't exist, I write them first. That's not overhead — it's the prerequisite.

Small steps, frequent commits

I refactor in tiny increments. Rename a variable. Extract a function. Move a method. Each step is small enough that if a test breaks, I know exactly what caused it.

After each successful change, I commit. Private commits to my local branch. If I mess up later, I can roll back to the last working state instantly. I squash the commits before pushing.

If someone says their code was broken for a couple of days while they were refactoring, you can be pretty sure they were not refactoring.

Real refactoring never breaks the code for more than a few minutes. If it does, the steps are too large.

When to refactor

Before adding a feature. If the code isn't structured to accommodate the new feature, refactor first. Make the change easy, then make the easy change.

During code review. If you see something unclear, clean it up. Follow the camping rule:

Always leave the code base healthier than when you found it.

When you feel friction. If a section of code is hard to modify, hard to test, or hard to understand, that's a signal. The friction is telling you the design needs improvement.

The Two Hats

I switch between two modes: adding functionality and refactoring. When I'm adding a feature, I don't restructure existing code. When I'm refactoring, I don't add new behavior. Mixing the two makes it impossible to know whether a test failure is from the new feature or the restructuring.

One hat at a time.

Good naming matters more than you think

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Breaking a large function into smaller ones only adds value if the names are good. A function called doStuff extracted from a larger function called handleAll is not a refactoring win. It's just moving the mess around.

The key insight

The true test of good code is how easy it is to change it.

Refactoring is how you keep code easy to change. Not through one big rewrite, but through continuous small improvements. Every time you touch code, you have a choice: leave it as is, or leave it slightly better.

Choose better. The compound interest on clean code is extraordinary.

Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

Refactoring (verb): to restructure software by applying a series of refactorings without changing its observable behavior.

The key to effective refactoring is recognizing that you go faster when you take tiny steps.