skip to content
~/amin
← cd ~/courses/solid

lesson 1/5 · 0:58

Single Responsibility Principle

Why one team's change can break another team's feature, and how splitting a class by "reason to change" stops it.

“A class should have only one reason to change.”

— Robert C. Martin

The story

Tony runs his pizza shop alone until it falls apart, so he hires help. Now a new delivery area changes only the driver’s job. Nobody else has to relearn anything.

The problem in code

Code has Tonys too: one UserService that Product, Marketing and Design all ask to change. Design wants lowercase avatar file names, you edit a name helper, and because sign-up uses the same helper, new users are saved with the wrong name.

class UserService {
  register(name: string, email: string) {
    const user = { name: this.normalize(name), email };
    db.save(user);
    this.sendWelcomeEmail(user);
  }

  sendWelcomeEmail(user: User) { /* Marketing's rules */ }

  uploadAvatar(user: User, file: File) {
    storage.put(this.normalize(user.name) + '.png', file); // Design's rules
  }

  // Shared helper: changing it for avatars also changes sign-up.
  private normalize(name: string) {
    return name.trim().toLowerCase();
  }
}

The fix

Split the class so each team owns its own piece. A change requested by Design now lands only in AvatarStore.

class Registration {
  constructor(private mailer: Mailer) {}
  register(name: string, email: string) {
    const user = { name: name.trim(), email };
    db.save(user);
    this.mailer.sendWelcome(user);
  }
}

class Mailer {
  sendWelcome(user: User) { /* Marketing's rules */ }
}

class AvatarStore {
  upload(user: User, file: File) {
    storage.put(user.name.toLowerCase() + '.png', file); // Design's rules
  }
}

Takeaway

“Responsibility” means reason to change, usually a person or team who asks for changes. If two teams edit the same class, split it.