SOLID Principles
There are 5 important principles in OOP : SRP, OCP, LSP, ISP, DIP.
What are those for? Let’s take a look at each principle.
Single-Responsibility Principle
There should be only one reason to change for a module. One job per module. Let’s say there is a class that has two jobs, A and B. Requirements of job A changes, but job B has been affected as well because they are in the same class. The code within the class regarding job B needs to be checked or changed when only job A has changed. If there were two separate classes for each job, this wouldn’t be happening. This principle also improve readability and ease maintenance. Imagine a class with 10 jobs intertwined all together within one class. It will be hard to figure out which lines belong to which job.
Open-Closed Principle
A module should be open for extension but closed for modification. Behaviors of a module should be extended by adding new code without changing existing code. Existing code is reused and it means easier maintenance. The more you change, the more you have to test.
The points that can vary should be abstracted away so that new requirements can be taken care of by new classes. For example, a class used for candy packaging with code programmed to concrete candy implementations using a lot of ‘if’s violates this principle. Whenever there is a new type of candy to be packaged, the class has to be modified. Instead, an interface of candy can be created and packaging class can abstract the candy part. More abstract classes(interface) should be used in code rather than concrete implementations wherever possible.
The difficulty of implemeting this principle is that it is not easy to anticipate what will vary and how the application will evolve in the future.
Liskov Substitution Principle
Get J’s stories in your inbox
Join Medium for free to get updates from this writer.
References to superclasses should be replaceable with objects of derived classes. When there are multiple interchageable subclasses for a superclass, code becomes much more flexible.
Subclasses should not violate the contract of superclasses. Unexpected error when switching to a different subclass object is a clear violation of LSP. Careful design of interface can prevent violation of LSP by not adding features that implementing classes don’t need.
Interface Segregation Principle
Clients should not be forced to depend on interfaces that they do not use.
Another example with the candy packaging class: implementing an interface with both cutting methods and packaging methods is a clear violation of this principle. The class may have to override methods regarding cutting when it doesn’t need to do any cutting. Also, this will result in lower cohesion.
When an interface is large and general, clients might use only some of the interface’s functionalities. Small and focused interfaces will prevent violating ISP just like in the case of LSP.
Dependency Inversion Principle
High level modules should not depend upon low level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.
Again, an example with the candy packaging class. If the candy packaging class depends on the concrete implementation for packaging, code might have to change when switching to a different packaging class. This can be refactored by making the candy packaging class depend on the interface for packaging, rather than a concrete packaging class. At the same time, the concrete packaging class also become dependent on the packaging interface.
It will not be always possible to follow these principles 100%, but keeping in mind and trying to incorporate these principles will help programmers write much more flexible, reusable and maintainable code.








