A software system can be compared to a game of Jenga. The Jenga tower is always changing and expanding—that’s the game. The more solid the foundation, and the less dependent each piece is on another, the more successful the Jenga game will be.
I’ve written about object-oriented software development (OOD) before. This time, I want to dive into another OOD framework for ensuring quality code: SOLID principles.
SOLID is made up of the first five principles in OOD, established by Robert C. Martin, aka Uncle Bob. Lucky for us, they spell a real word.
- S - Single-responsibility principle
- O - Open-closed principle
- L - Liskov substitution principle
- I - Interface segregation principle
- D - Dependency inversion principle
Each principle stands on its own as an indicator of quality code. But they also work together. If you’re a developer, learn how to program with the five SOLID principles. If you’re a client, ask your developers how they plan to use SOLID principles while creating your solution. If you work with or manage developers, get them on board with SOLID.
S - Single-responsibility principle
A class should have one and only one reason to change. In other words, a class should only have a—wait for it—single responsibility. This principle is simple, but not always easy to follow. It’s tempting to sneak new responsibilities into existing classes, but that’s likely to cause future issues. Save yourself time later, and make the new class now.
O - Open-closed principle
Objects or entities should be open for extension, but closed for modification. Basically, a class should be easily extensible without requiring modification of the class itself. The goal of this principle is to help create well-encapsulated, highly cohesive systems. We’ve found following the open-close rule really helps when multiple developers are involved—less system-specific domain knowledge is required to make updates and expansions.
L - Liskov substitution principle
Derived types must be completely substitutable for their base types. New derived classes must just extend without replacing the functionality of old classes. Otherwise, the new classes can produce undesired effects if they’re used in existing program modules.
I - Interface segregation principle
Clients (here, referring to classes or modules) should not be dependent upon interfaces or methods they don't use. Keeping interfaces segregated helps a developer more easily know which one to call for specific functions and helps us avoid fat or polluted interfaces that can affect the performance of a system. Doing so also helps us write better unit tests on the codebase.
D - Dependency inversion principle
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions. This principle helps maintain a system that’s properly coupled. Avoiding high-level class dependencies on low-level classes helps keep a system flexible and extensible.
Using SOLID principles is critical to being a really good programmer and creating valuable software solutions. SOLID is essentially a balanced nutrition plan for software development. When we don’t use these principles in development, our code base becomes bloated and overweight. The system then requires extra work and attention to “trim down” or even maintain, and is at much higher risk for an emergency scare (think heart attack = system failure).
If you want to dive deeper into SOLID principles, here’s information specifically for C#
, here’s a class on Pluralsight
, and we read Adaptive Code via C#: Agile coding with design patterns and SOLID principles
in our developer book club.