Do You Need SOLID to Be a Better Developer?
You don’t need SOLID to write working code—many developers manage without it. But to become a better developer (and potentially earn more by writing high-quality, maintainable software), learning SOLID basics is a smart move. SOLID’s five principles make code more understandable, flexible, and maintainable.
1. Single Responsibility Principle
"Do one thing and do it well"—that’s Uncle Bob’s advice from his book. SRP means a class should have just one responsibility.
SRP Failing
The Book
class has two responsibilities:
- Managing book details (title, author, description)—its core purpose.
- Interacting with a database (
saveToDatabase
)—unrelated to the book’s properties. That’s a mistake.
SRP Essence
To fix this, separate the responsibilities:
-
Book
focuses solely on book-related tasks. -
DatabaseManager
handles database operations. Each class now has one reason to change: -
Book
if book properties change. -
DatabaseManager
if database logic changes.
2. Open/Closed Principle
The Open/Closed Principle (OCP) means software entities (classes, modules) should be open for extension but closed for modification—add new functionality without altering existing code.
OCP Failing
The ShippingCalculator
calculates shipping costs based on book type.
The mistake?
Adding a new type requires modifying it with another elseif
, breaking OCP. This opens the class to changes, risking bugs.
OCP Essence
The ShippingCalculator
stays closed for modification by using a ShippingType
interface. New types (PaperbackShipping
, HardcoverShipping
) extend it, delegating logic to specific classes. This keeps the system flexible and bug-free.
3. Liskov Substitution Principle
The Liskov Substitution Principle (LSP) states that subclass objects should replace parent class objects without breaking the program—substitution should work seamlessly.
LSP Failing
A Bird
class assumes all birds can fly()
, but a Penguin
subclass can’t. This breaks LSP because Penguin
isn’t substitutable for Bird
without altering behavior.
LSP Essence
An Animal
interface with a move()
method lets Sparrow
and Penguin
implement it their way. The makeAnimalMove()
function works with any Animal
subclass without breaking, satisfying LSP.
4. Interface Segregation Principle
ISP states that classes shouldn’t be forced to implement interfaces they don’t use—keep interfaces small and specific.
ISP Failing
A Worker
interface includes work()
and manage()
. Developer
only needs work()
but must implement manage()
too, breaking ISP by forcing unused methods.
ISP Essence
Workable
and Manageable
are separate interfaces. Developer
implements only Workable
; Manager
implements both. No unused methods are forced, satisfying ISP.
5. Dependency Inversion Principle
DIP states that high-level modules shouldn’t depend on low-level ones—both should rely on abstractions (interfaces) for flexibility.
DIP Failing
Notification
(high-level) directly depends on FileLogger
(low-level). Switching to DatabaseLogger
requires changing Notification
, breaking DIP due to tight coupling.
DIP Essence
A Logger
interface defines the contract. Notification
depends on Logger
, not FileLogger
. Swapping FileLogger
for DatabaseLogger
needs no changes to Notification
, following DIP by relying on abstractions.
Final Thoughts
SOLID principles improve code quality and flexibility. Apply them to level up your skills and projects. Thanks for reading!
Top comments (2)
I would not use the open/close example because the book type is just a characteristic of a book. By linking that characteristic to shipping the code adds a too specific context. Which breaks the single reponsibility.
For the Liskov Substitution the example is bad because the fix removes a more defined class.
A better fix is to remove the
fly
function.side node: Can you please use the code block markdown instead of the images. That way it is readable for everyone.
Thanks for the comment, this is my first post i will make it better !!