yeah, fair point. the penguin example is more of an intuitive way to understand lsp, but the harder cases are where the subclass technically has all the methods but changes the behaviour the parent contract promises.
honestly, i don't even know if i fully get it yet, i still find myself looking it up whenever i want to understand it better. i need to see more real world examples
learned about the SOLID principles today.
i already knew the basics of oops, so getting through the fundamentals was pretty quick. but SOLID takes those concepts a step further and helps you think about how to structure code as the system grows
so why should every developer learn SOLID Principles?
because writing code that works is one thing. writing code that's easy to understand, maintain, test and extend is a completely different skill
solid helps you:
โ reduce unnecessary coupling
โ make changes safer
โ keep responsibilities clear
โ make code easier to test and extend
โ build systems that can scale without turning into a mess
there are 5 principles:
โ single responsibility
โ open/closed
โ liskov substitution
โ interface segregation
โ dependency inversion
breaking down each one in this thread ๐งต๐
5/5 Dependency Inversion Principle
The dependency inversion principle (DIP) says that high level modules shouldn't depend directly on low-level modules. Both should depend on abstractions
Instead of having:
notificationservice โ emailservice
we can have:
notificationservice โ notificationsender โ emailservice
Now notificationservice doesn't care whether the notification is sent through email, sms or push.
This reduces coupling and makes it much easier to swap implementations, test your code and extend the system later.
and that's the 5 SOLID Principle
they might look simple individually, but understanding when and why to apply them is where most people struggle including me, :)
4/5 Interface Segregation Principle
Interface Segregation Principle(ISP) says that a class shouldn't be forced to implement methods that it doesn't actually need.
Instead of creating one massive interface with 20 different methods, it's often better to create smaller, focused interfaces.
for eg, instead of one huge worker interface containing work(), eat(), sleep() and other unrelated methods, you can split those responsibilities into separate interfaces.
this keeps interfaces simple and prevents classes from depending on functionality they don't use.