There’s one scene I come across remarkably often during code reviews.
You search for a feature to fix and find nearly identical code in three places. Fix one, and the other two remain as bugs.
Today’s main topic is DRY, the principle aimed directly at this problem. It goes hand in hand with the KISS principle we covered last time.
DRY stands for “Don’t Repeat Yourself.” It means not repeating the same knowledge within a system.
Andy Hunt and Dave Thomas outlined this concept in the 1999 book <The Pragmatic Programmer>, and the original definition is remarkably precise.
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
The key word here is not “code,” but “knowledge.” That is the core of today’s discussion.
Why Is Copy-Pasting Code a Problem?
Copying and pasting isn’t inherently wrong. The problem comes afterward.
If the same logic exists in three places, you have to find and update all three when requirements change. Miss even one, and it becomes a bug.
// Shipping-cost calculation is scattered across three files
// Cart.swift
let fee = total >= 50000 ? 0 : 3000
// Checkout.swift
let shippingFee = totalPrice >= 50000 ? 0 : 3000
// OrderSummary.swift
let delivery = price >= 50000 ? 0 : 3000
What if a request comes in one day to “lower the free-shipping threshold to 30,000 won”? You have to find all three files. Since the search terms differ, you’re bound to miss one.
// Centralize the knowledge in one place
// Shipping.swift
enum ShippingPolicy {
static let freeShippingThreshold = 50000
static let fee = 3000
static func shippingFee(for total: Int) -> Int {
total >= freeShippingThreshold ? 0 : fee
}
}
Now, when the policy changes, you only need to update one place. That’s DRY.
It’s Duplication of “Knowledge,” Not Code
But this is where many people stumble. They interpret DRY as “merge all code that looks similar.”
The duplication DRY refers to is not duplicated code shape, but duplicated knowledge—in other words, duplicated business rules.
This distinction matters because the world contains code that happens to look alike.
| Situation | Duplication? |
|---|---|
| Shipping-cost calculation in three places | Real duplication (same knowledge) |
| Sign-up validation and event-entry validation happen to look similar | False duplication (different knowledge) |
| The constant 3000 appears separately in shipping costs and the points-earning threshold | False duplication (different meaning) |
Sign-up validation and event-entry validation may look identical because both currently require a name and an 11-digit phone number, but the rules change for different reasons. Merge them, and changing the event rules may break sign-up.
Premature Abstraction Costs More Than Duplication
That’s why you often hear this in developer communities: “prefer duplication over the wrong abstraction.” It was said by Sandy Metz, a well-known Ruby developer.
Forcing two pieces of code that merely look similar into one creates this sequence of events.
- Create a common function
- One side changes, so you add an option parameter
- The other side changes too, so you add an if branch
- Before long, it becomes a five-parameter function nobody understands
At that point, two copied versions would have been better.
That’s why practitioners often use the Rule of Three. When a pattern appears twice, take note; when it appears a third time, abstract it. After three repetitions, it becomes clearer whether the knowledge is truly the same or merely coincidental.
The Criteria I Use
When I find duplication, I ask one question.
Do these two pieces of code change for the same reason?
If they change for the same reason, they are real duplication, so I merge them. If they change for different reasons, I leave them alone no matter how similar they look.
Today’s Takeaway
Here’s the DRY principle in a nutshell.
- The unit of duplication is knowledge (business rules), not code shape.
- Merge only code that changes for the same reason. Leave code that merely happens to look similar alone.
- If you’re unsure, use the Rule of Three. Abstracting on the third repetition is not too late.
If KISS means “keep it simple,” DRY means “keep knowledge in one place.” Ultimately, both are about reducing the cost of change.
You can probably think of a piece of logic that shows up in three places every time you search. That’s today’s refactoring candidate.

