Last updated: Apr 29, 2026

Single Responsibility

A class should have one reason to change. If a class mixes multiple concerns, split them.

Example

This Report class handles content, PDF formatting, and file storage all in one place:

class Report {
  generateContent(): string {
    return "content";
  }

  printToPdf(): void {
    // PDF formatting
  }

  saveToFile(): void {
    // file I/O
  }
}

Split into three classes, each with one job:

class Report {
  generateContent(): string {
    return "content";
  }
}

class PdfPrinter {
  print(report: Report): void {
    // PDF formatting
  }
}

class FileStorage {
  save(content: string): void {
    // file I/O
  }
}

Now when the PDF library changes, you only touch PdfPrinter. When you switch from files to a database, you only modify FileStorage. Each change is isolated.