Engineering Culture

The Rule of Three: When to Actually Abstract

DRY tells you never to repeat yourself. But the wrong abstraction costs more than duplication. Wait for the third copy before you generalize.

RE

Roberto Espinoza

CEO, Ruzora

July 26, 20268 min read

New engineers learn "Don't Repeat Yourself" early and apply it zealously: see two similar pieces of code, immediately merge them into a shared abstraction. It feels like good engineering. It's often the opposite, because the wrong abstraction is more expensive than the duplication it replaced. The rule of three exists to slow that reflex down.

Key Takeaways

  • The rule of three: wait until you see the duplication a third time before you abstract (rule of three)).
  • With only two copies, you can't tell if the similarity is real or coincidental (coincidental duplication).
  • Sandi Metz's rule: duplication is far cheaper than the wrong abstraction.
  • Prefer AHA (Avoid Hasty Abstractions, coined by Kent C. Dodds) over reflexive DRY (AHA).

The Rule

The rule of three, popularized in refactoring practice, is a heuristic for doubt: when you're tempted to abstract shared code, wait until the same duplication appears a third time before you extract it (rule of three)). The reasoning is about information. With two similar pieces of code, you don't yet know whether they're the same thing (and should be unified) or merely look alike by coincidence (and should stay separate). Two data points can't tell you which. By the third occurrence, the real pattern, and its true boundaries, has usually revealed itself, so the abstraction you build actually fits.

Why the Wrong Abstraction Is So Costly

DRY isn't wrong; over-eager DRY is. Sandi Metz put the danger memorably: duplication is far cheaper than the wrong abstraction. Here's the trap (the wrong abstraction). You see two similar functions and merge them into one shared function with a parameter to handle the differences. Then requirements change, and the two cases start to diverge, so you add another parameter, then a conditional, then a flag. Soon the shared abstraction is a tangle of special cases serving callers that no longer have much in common, and it's harder to understand and change than the duplication ever was. Worse, it's now load-bearing, so untangling it is a scary refactor rather than a simple copy edit.

Coincidental duplication is the specific danger: two pieces of code that happen to look identical today but represent different concepts. Abstract them together and you freeze a coincidence into your architecture, forcing every future change to fight it (DRY vs WET vs AHA).

Reflexive DRYRule of three / AHA
Abstract at the 2nd copyWait for the 3rd
Assumes similarity is realWaits to learn if it's real
Freezes coincidencesAbstracts proven patterns
Wrong abstraction is costlyDuplication is cheaper meanwhile

A Concrete Version

An engineer sees two API handlers that look nearly identical and DRYs them into one shared handler with an "isAdmin" flag. It's clean, briefly. Then admin and user requirements diverge: different validation, different rate limits, different response shapes. Each divergence adds a branch to the shared handler, until it's a thicket of "if admin do this, else do that" that both callers have to reason about. Two separate handlers with a little duplicated boilerplate would have been easier to read and change the whole time. The abstraction merged two things that were only coincidentally alike.

The Honest Counterpoint

The rule of three can be taken too literally and become an excuse for genuine copy-paste sprawl. Some duplication is obviously the same thing and should be unified immediately, a core business rule, a security check, a validated calculation, where three divergent copies would be a real bug waiting to happen. DRY earns its reputation for exactly those cases: knowledge that must have a single source of truth. The nuance is to distinguish duplicated knowledge (unify it, even early) from duplicated code that merely looks similar (wait, it may diverge). The rule of three is a heuristic for the ambiguous middle, not a ban on ever abstracting early when the concept is genuinely one thing.

What This Means for Teams

Knowing when to abstract is a surprisingly strong signal of engineering maturity. Junior engineers over-apply DRY and build premature, brittle abstractions; senior engineers tolerate a little duplication until the right shape reveals itself, and can tell duplicated knowledge from coincidental similarity. That restraint, resisting a clean-looking abstraction because you don't yet know if it's the right one, is the same "avoid premature complexity" judgment behind YAGNI and choosing boring technology, and it's part of what we screen for in how to verify a senior engineer. See available engineers.

Frequently Asked Questions

What is the rule of three?

A refactoring heuristic: wait until you see the same duplication a third time before extracting it into an abstraction. Two copies can't tell you whether the similarity is real or coincidental; the third usually can.

Isn't DRY (Don't Repeat Yourself) good?

For duplicated knowledge, yes, a business rule or security check should have one source of truth. The danger is applying DRY reflexively to code that merely looks similar, which risks building the wrong abstraction.

Why is the wrong abstraction so costly?

Because as requirements diverge, a premature shared abstraction accumulates parameters, flags, and conditionals to serve callers that no longer match, becoming harder to understand and change than the duplication was, and scarier to untangle.

What is AHA?

"Avoid Hasty Abstractions," a term coined by Kent C. Dodds that echoes Sandi Metz's point: resist abstracting until the right shape is clear, on the basis that duplication is far cheaper than the wrong abstraction.

The Bottom Line

DRY is right about duplicated knowledge and dangerous when applied reflexively to code that only looks alike, because the wrong abstraction costs more than the duplication it replaces. Wait for the third occurrence before you generalize, so the real pattern and its boundaries have revealed themselves. A little patience with duplication beats freezing a coincidence into your architecture.

Roberto Espinoza is CEO of Ruzora, which helps US startups hire pre-vetted senior LATAM engineers, with a vetted shortlist in 72 hours. See available engineers.

RE

Roberto Espinoza

CEO, Ruzora

Roberto is the founder and CEO of Ruzora. He works directly with US startup founders and CTOs on staff-augmentation and software-factory engagements, and personally reviews senior engineer placements.

AI-vetted engineers, ready now

Your next senior engineer is already vetted and waiting.

It starts with a single call. 72 hours later, you're reviewing scored candidates who already match your stack and culture.