Refactoring & Code Quality
Technical Debt
Ward Cunningham's metaphor: a shortcut taken now accrues interest as slower, riskier future changes — useful precisely because it reframes "messy code" as a deliberate, trackable financial trade-off rather than a moral failing.
- The 2×2: reckless/prudent crossed with deliberate/inadvertent — only one quadrant (reckless-and-inadvertent) is pure carelessness
- Interest is the ongoing cost of working around the debt — every future change in that area takes longer than it would on clean code
- Debt should be visible and tracked (a backlog item, a
TODOwith a ticket link), not silently absorbed into "how things are" - Pay down debt when the interest it's accruing exceeds the cost of fixing it — not on a fixed schedule and not out of tidiness alone
- A full rewrite is rarely the cheapest way to pay off debt — incremental refactoring under test coverage usually costs less and never leaves you without a working system
| Deliberate | Inadvertent | |
|---|---|---|
| Reckless | "We don't have time for design" | "What's layering?" |
| Prudent | "We must ship now and deal with consequences" (a real, informed trade-off) | "Now we know how we should have done it" (learning is normal) |
Cunningham's original point is often flattened into "sloppy code is debt," but his actual metaphor was about learning as you build: you ship your best understanding of the design today, and as the system teaches you more, some of that understanding turns out to be wrong — the gap between what you shipped and what you'd build knowing what you know now is the debt, and it is a completely normal byproduct of building anything non-trivial, not a sign anyone did something wrong. The reckless/deliberate quadrant ("we know this is bad, ship it anyway, no plan to fix it") is the only genuinely blameworthy one.