What do YAGNI, DRY and KISS mean, and can they conflict?
Quick Answer
YAGNI — don't build what you only think you'll need. DRY — every piece of knowledge should have one authoritative representation. KISS — prefer the simplest thing that works. They can conflict: aggressively DRY-ing incidental duplication creates a premature, awkward abstraction that violates KISS and YAGNI.
YAGNI is “you aren't gonna need it” — don't add flexibility or features on speculation. DRY is don't repeat knowledge — a business rule should live in one place. KISS is keep it simple. They tension against each other: if I see two similar-looking blocks and immediately extract a shared method, I might be DRY-ing code that only looks the same by coincidence and will diverge, and now I've got an awkward abstraction that's neither simple nor something I needed. My rule is the rule of three — I let it repeat until I've seen it three times and actually understand the shared concept, then I abstract.
- DRY is about knowledge, not text — two methods that look similar today but change for different reasons are not a DRY violation.
- The “rule of three”: tolerate duplication until the third occurrence, then abstract, because by then you understand the real shared concept.
- YAGNI pushes back on speculative generality — interfaces with one implementation “for flexibility”, config options nobody asked for.
- Some duplication (WET — write everything twice) is cheaper than the wrong abstraction.