What are the SOLID principles?
Quick Answer
SOLID is five object-oriented design principles: Single Responsibility (a class has one reason to change), Open/Closed (open for extension, closed for modification), Liskov Substitution (a subtype must be usable wherever its base type is), Interface Segregation (many small interfaces beat one fat one), Dependency Inversion (depend on abstractions, not concretions).
SOLID is five principles for keeping object-oriented code maintainable. Single Responsibility — a class should have one reason to change, so I don't put business logic, email formatting and file I/O in the same class. Open/Closed — I add features by adding new classes, not editing existing ones, usually via polymorphism. Liskov — a subclass has to work anywhere the base class works without surprising the caller. Interface Segregation — small focused interfaces instead of one giant one. And Dependency Inversion — my high-level code depends on an interface, and the concrete implementation is injected, which is exactly what DI does. I treat them as guidance for limiting the impact of change, not rules to follow blindly.
- SRP —
OrderServiceshouldn't also format emails and write files. Split responsibilities so one change touches one class. - OCP — add new behaviour by adding a class (a new
IDiscountRule), not by editing a bigswitch. Achieved with polymorphism and strategy-style designs. - LSP — if
Square : Rectanglebreaks code that sets width and height independently, the hierarchy is wrong. Subtypes must honour the base type's contract (no strengthened preconditions, no weakened postconditions). - ISP — a client forced to implement
IRepositorywith 20 methods when it needs 2 signals a fat interface. Split intoIReadRepository,IWriteRepository. - DIP — high-level policy and low-level details both depend on an interface.
OrderServicedepends onIPaymentGateway; the concreteStripeGatewayis injected. This is what dependency injection operationalises.
SOLID is guidance, not law — applied blindly it produces a maze of tiny classes. Use it to reduce the blast radius of change.
- One reason to change
- Split cohesive concerns
- Smaller, focused classes
- Extend, don't modify
- Add a class, not a case
- Strategy pattern
- Subtype honours contract
- No stronger preconditions
- Square/Rectangle problem
- Small interfaces
- Clients depend on what they use
- Split fat repositories
- Depend on abstractions
- Inject concretions
- Powers DI containers
- Confusing the Dependency Inversion Principle with dependency injection (the technique) or with an IoC container (the tool).
- Applying SRP so aggressively that every method becomes its own class — indirection without benefit.
- Claiming a hierarchy follows LSP when overriding a method to throw
NotSupportedException. - Treating SOLID as a checklist to satisfy rather than a tool for reducing the cost of change.