Solid
In 2003, software engineer Robert C. Martin presented the core ideas that would become SOLID during a talk at the 2009 Gotham Ruby Conference. He had introduced these basic principles in his 2000 paper titled Design Principles and Design Patterns about software rot. The acronym itself did not exist when he first spoke of them. Michael Feathers coined the term SOLID around 2004 to group these five concepts together. This mnemonic now guides developers who want their code to remain understandable over time. It also serves as a philosophy for agile software development teams adapting to change.
The single responsibility principle states there should never be more than one reason for a class to change. Every class must hold only one specific job within the system. When classes carry a single well-defined responsibility they become easier to understand. Developers find it simpler to modify code that focuses on one task alone. Unit tests grow easier to write because each class has a narrow focus. Changes to one responsibility will not ripple out to affect unrelated parts of the system. This isolation keeps large projects from becoming tangled messes of interdependent logic.
Software entities should be open for extension but closed for modification according to the open-closed principle. New features can be added without touching existing source code lines. Reducing modifications lowers the risk of introducing new bugs into stable systems. Teams adapt to changing requirements more easily when they follow this strategy. Stability increases because core logic remains untouched while behavior expands outward. Flexibility allows the architecture to evolve without constant rewrites of foundational components.
Functions using pointers or references to base classes must handle derived class objects without knowing the difference. Polymorphism enables flexible and reusable code through this substitution mechanism. Subclasses adhere strictly to the contract defined by their superclass. Replacing a superclass object with a subclass object will never break the program. Reliability improves as developers trust that any derived type behaves correctly within the system. Predictability ensures that swapping implementations does not introduce hidden failures in critical paths.
Clients should not be forced to depend upon interfaces they do not use. This rule prevents unnecessary dependencies between modules and keeps code modular. Developers gain flexibility by allowing targeted implementations of specific interface methods. Decoupling reduces the number of connections required between different parts of an application. Systems become easier to maintain when unused functionality is removed from client views. Teams avoid building large bloated interfaces that force every user to implement irrelevant methods.
Developers must depend upon abstractions rather than concrete implementations to reduce coupling. Loose coupling makes systems more flexible and significantly easier to test. Changes to specific implementations no longer affect the clients relying on them. Code becomes simpler to understand when high-level modules do not know about low-level details. Maintainability increases because teams can swap out components without rewriting entire sections. Flexibility allows new features to integrate smoothly into existing architectures without breaking contracts.
Up Next
Common questions
When did Robert C. Martin present the core ideas that became SOLID?
Robert C. Martin presented the core ideas during a talk at the 2009 Gotham Ruby Conference in 2003.
Who coined the term SOLID and when was it created?
Michael Feathers coined the term SOLID around 2004 to group five concepts together.
What does the single responsibility principle state about classes?
The single responsibility principle states there should never be more than one reason for a class to change.
How does the open-closed principle allow new features to be added?
New features can be added without touching existing source code lines according to the open-closed principle.
Why must clients not depend upon interfaces they do not use?
Clients should not be forced to depend upon interfaces they do not use to prevent unnecessary dependencies between modules.