Engineering Playbook
Code Structure

SOLID Principles

The five commandments of Object-Oriented Design.

SOLID Principles

SOLID is a set of five design principles intended to make software designs more understandable, flexible, and maintainable. While originating in OOP, they apply to almost any modular system.

The Five Principles

S — Single Responsibility Principle (SRP)

"A class should have one, and only one, reason to change."

  • Bad: A User class that handles authentication, saves to the DB, and generates PDF reports.
  • Good: Separate UserAuth, UserRepository, and UserReportGenerator classes.
  • Why: If you change the PDF library, you shouldn't risk breaking the Login logic.

Key Idea: Split responsibilities into focused classes that each handle one concern.

O — Open/Closed Principle (OCP)

"Entities should be open for extension, but closed for modification."

  • Scenario: You have a ShapeAreaCalculator.
  • Bad: Modifying the class with if (shape == 'circle') ... else if (shape == 'square').
  • Good: The Calculator accepts a Shape interface. You create a new Circle class that implements area(). The Calculator code never changes.

Key Idea: Use interfaces and polymorphism to extend functionality without changing existing code.

L — Liskov Substitution Principle (LSP)

"Subtypes must be substitutable for their base types."

  • The Test: If Duck is a subtype of Bird, but Duck throws an error when you call fly() (because maybe it's a rubber duck), you violated LSP.
  • Impact: Breaking this leads to fragile inheritance hierarchies filled with type checks.

Key Idea: Design inheritance hierarchies where child classes can truly replace their parents without breaking functionality.

I — Interface Segregation Principle (ISP)

"Many client-specific interfaces are better than one general-purpose interface."

  • Bad: An IVehicle interface with drive() and fly(). A Car class is forced to implement fly() (throwing an error).
  • Good: Split it into IDrivable and IFlyable.
  • Mantra: No client should be forced to depend on methods it does not use.

Key Idea: Create small, focused interfaces instead of large, general-purpose ones.

D — Dependency Inversion Principle (DIP)

"Depend on abstractions, not on concretions."

  • Concept: High-level modules (Business Logic) should not import low-level modules (Postgres Driver). Both should import an Interface.
  • This is the foundation of Clean Architecture.

Key Idea: Both high-level and low-level modules should depend on abstractions (interfaces), not on concrete implementations.

Don't Over-Engineer

SOLID is a goal, not a religion. Applying OCP to a script that will never change is wasted effort. Use judgment.