DRY, KISS, YAGNI
Three foundational principles for writing clean, maintainable code.
DRY - Don't Repeat Yourself
Every piece of knowledge should have a single, unambiguous representation in the system.
Goal: Avoid code duplication. If you change logic, change it in one place.
Violation
// Same validation in multiple places
void createUser(String email) {
if (!email.contains("@")) throw...
}
void updateEmail(String email) {
if (!email.contains("@")) throw...
}Following DRY
// Single validation method
void validateEmail(String email) {
if (!email.contains("@")) throw...
}
void createUser(String email) {
validateEmail(email);
}
void updateEmail(String email) {
validateEmail(email);
}When NOT to DRY
Don't over-abstract. If two pieces of code look similar but serve different purposes and may evolve differently, it's okay to keep them separate.
KISS - Keep It Simple, Stupid
Simplicity should be a key goal in design. Avoid unnecessary complexity.
Goal: Write code that's easy to understand, debug, and maintain.
Over-engineered
// Too complex for simple task
interface StringProcessor {
String process(String s);
}
class UpperCaseProcessor
implements StringProcessor {
public String process(String s) {
return s.toUpperCase();
}
}
class ProcessorFactory {
static StringProcessor get() {
return new UpperCaseProcessor();
}
}Simple & Clear
// Just do what's needed
String toUpperCase(String s) {
return s.toUpperCase();
}Signs of Over-Engineering
- - Many abstraction layers for simple tasks
- - Design patterns used without clear benefit
- - "Future-proofing" for requirements that don't exist
- - Code that's hard to explain to teammates
YAGNI - You Aren't Gonna Need It
Don't add functionality until it's actually needed. Avoid building features based on speculation.
Goal: Focus on current requirements. Add features when needed, not before.
Premature Features
class User {
String name;
String email;
// "We might need these later"
String facebookId;
String twitterId;
String linkedinId;
List<String> hobbies;
Map<String, Object> metadata;
boolean isPremium;
int loyaltyPoints;
}Only What's Needed
class User {
String name;
String email;
// Add fields when actually
// required by a feature
}Cost of Premature Features
- - Development time wasted
- - Code to maintain forever
- - Increased complexity
- - Often built wrong anyway (requirements change)
Quick Reference
| Principle | Meaning | Action |
|---|---|---|
| DRY | Don't Repeat Yourself | Extract duplicated code into reusable functions |
| KISS | Keep It Simple, Stupid | Choose the simplest solution that works |
| YAGNI | You Aren't Gonna Need It | Don't build features until needed |
Interview Tips
- 1.When asked about code quality, mention these three principles
- 2.DRY is about knowledge, not just code - avoid duplicating business logic
- 3.Balance is key: too DRY leads to over-abstraction, too KISS ignores extensibility
- 4.YAGNI saves time - build for today's requirements, refactor when needed