DRY Is Overrated

Duplication isn't the enemy — premature abstraction is.

❌ Over-Abstracted
// The "Universal" Handler
function saveData(data, type) {
  const db = connect();

  // Coupling: Change one, risk breaking others
  if (type === 'user') {
    validateUser(data);
  } else {
    validateOrder(data);
  }

  save(type, data);
}
✅ Duplicate & Decouple
// Independent: Evolve freely
function saveUser(user) {
  validateUser(user);
  db.users.add(user);
}

function saveOrder(order) {
  validateOrder(order);
  // Orders might need an API call instead!
  api.orders.submit(order);
}

Why DRY Fails in Practice

Premature Merging

Code that looks similar isn't always conceptually related. Merging unrelated code couples things that should evolve independently.

Tight Coupling

Shared helpers create invisible dependencies. Change one thing, break three others. The "Monolithic Object" anti-pattern starts here.

Indirection

Every abstraction adds a layer of cognitive load. Too many layers make code impossible to trace for newcomers.

The Reality: Duplication is cheaper than the wrong abstraction. It is easier to fix duplication later than to dismantle a complex, incorrect abstraction.

Better Heuristics

AHA

Avoid Hasty Abstractions. Wait until you fully understand the pattern before you abstract.

WET

Write Everything Twice. It's okay to copy-paste. Abstract only on the third time (or fourth).

YAGNI

You Aren't Gonna Need It. Don't build for hypothetical futures. Build for today.

Resources