LLD/Design Principles

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

PrincipleMeaningAction
DRYDon't Repeat YourselfExtract duplicated code into reusable functions
KISSKeep It Simple, StupidChoose the simplest solution that works
YAGNIYou Aren't Gonna Need ItDon'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