software engineering3 min read
SOLID principles, with pros and cons

The SOLID principles are five widely used guidelines for object-oriented design. Robert C. Martin collected them in the early 2000s, and Michael Feathers came up with the acronym. They give a useful framework for building software that is easier to maintain and extend, as long as you also weigh what each one costs.
S: single responsibility principle (SRP)
A class should have only one reason to change, which in practice means it should do one job. In formal terms: take a class C and the set of its responsibilities R(C) = {r1, r2, ..., rn}. SRP says that |R(C)| = 1.
Pros
- Easier maintenance: a change to one responsibility doesn't affect others.
- High cohesion: each class is focused, so it's easier to understand and manage.
Cons
- Complexity: SRP can lead to many more classes, which makes the architecture harder to navigate.
- Dependency risks: highly focused classes often need to talk to each other more, which adds dependencies.
O: open/closed principle (OCP)
Software entities should be open for extension but closed for modification. The idea goes back to Bertrand Meyer (1988). Formally, given a class C, new functionality f should be added by extending C rather than changing its existing code.
Pros
- Flexibility: new functionality can be added without changing existing code.
- Lower risk: changes are less likely to introduce bugs into the existing system.
Cons
- Indirection: new functionality often needs extra layers, which adds complexity.
- Overhead: extra classes and interfaces make the code harder to learn.
L: Liskov substitution principle (LSP)
Derived classes must be substitutable for their base classes. Barbara Liskov stated the idea in 1987. For a base class B and a derived class D, if D is a subtype of B, then objects of type B can be replaced with objects of type D without changing the desirable properties of the program. Substitution goes one way only: a child can stand in for its parent, not the other way round.
Pros
- Substitutability: code written against the base type works with any well-behaved subtype, which makes it more flexible.
- Reuse: code that depends on the base class can be reused with every subclass that keeps its contract.
Cons
- Restriction: it limits how derived classes can be implemented.
- Design complexity: it takes careful planning to make sure every derived class honours the base class's contract.
I: interface segregation principle (ISP)
A client shouldn't be forced to depend on methods it doesn't use. Formally: for an interface I and its clients C, if some clients use only part of I, split I into smaller, role-specific interfaces so that each client depends only on the methods it needs.
Pros
- Decoupling: clients aren't affected by changes to methods they don't use.
- Fine-grained control: clients can depend on just the interfaces they need.
Cons
- Too many interfaces: it can lead to lots of small, specialised interfaces.
- Maintenance: more interfaces can be harder to manage.
D: dependency inversion principle (DIP)
High-level modules shouldn't depend on low-level modules; both should depend on abstractions. Formally: let H and L be a high-level and a low-level module. If H depends on L, invert the dependency through an abstraction A, so that H depends on A and L depends on (implements) A.
Dependency injection is a common way to apply DIP, but they aren't the same thing: DIP is about which way dependencies point, and injection is one technique for supplying the concrete implementation.
Pros
- Modularity: it's easier to swap in different implementations.
- Testability: because code depends on abstractions, tests can supply fakes, often through dependency injection.
Cons
- Indirection: extra layers of abstraction can complicate the system.
- Development time: designing good abstractions takes time.
Summary
The SOLID principles give a solid foundation for building maintainable software. They bring real benefits, such as modularity and testability, but the extra complexity and dependencies they introduce need managing too. Knowing the pros and cons of each principle helps you decide when to apply it and when not to.