What is Interface Segregation Principle – ISP
The interface segregation principle aims to reduce the client dependency on methods that does not need. The target of that principle is to prevent modifying, redeploying or testing a client if one of its dependency modified a method that is not used by the client. How to do that? Do not depend on an interface that has methods that you do not use. In general a client should not be forced to use an interface with methods it does not need.
Many client specific interfaces are better than one general purpose interface.Robert C. Martin
Design Principles and Design Patterns.
Based on that while designing a software consider that many client specific interfaces are better than one general purpose interface. In other words, it is better to have a lot of smaller interfaces than a few bigger ones. That means you should make fine grained interfaces that are client-specific and clients should not be forced to implement interface methods they do not use.
This diagram illustrates depending on one big interface that has many methods are not used by the clients is painful approach to manage the changes.
The diagram shows the big interface broken up into three smaller interfaces to be specific to the clients needs. This approach easier to manage the changes.
While adding a new feature do not add new methods to existing interface, create new interface for a new feature. As changing an existing interface will lead to a cascaded changes in all clients uses that interface and will increase the scope of testing and probability of failures and generating new bugs for existing stable features. Hence software engineers should avoid the temptation of having one big, general-purpose interface and they should create many client-specific interfaces.
Example on ISP
Let’s have an example of a DAO interface that can insert or add a new blog post in a blogging application and at the same time it can read or get a blog post by ID. That interface is used by blog administration client to write posts and at the same time it is used by the blog viewer client to view the blogs to the blog visitors. The problem in that design is the clients need to store the data do not need to implement the the read methods and the clients need to read the data do not need to implement the store methods. Hence any change in read methods will impact the clients store the data unnecessarily. On the other hand any change in store methods will impact read clients and they should not be impacted.
Refactoring the example
A better approach is shown in the above UML diagram is to split the data modification logic from the data queries logic. In that design the clients need to store data do not have access to the methods that read data and vice versa. That design follows the interface segregation principle and the Command Query Responsibility Segregation (CQRS). CQRS is one of the applications of ISP principle and it focus on decoupling the data modification front he data query logic. The CQRS enable to scale read services and write services independently.
Why to follow ISP.
In a system that depedends on a Framework that depedends on a specific databse engine, the framework doesnot require all the features in the dabase, but if any of these features changed, the framework will need redeployment and the system sues the framework will need redeployment. Moreover a failure in one of the database features could cause a faulire in the framwork F and System S. Hence, depending on something that carries baggage that you, don’t need can cause you troubles that you didn’t expect, that was mentioned in clean architecture book by Robert C. Martin.
Following ISP lower coupling because making clients depend on interfaces they actually need, eliminate the risk of changing the client code because of some change not related to the methods used by the client. Hence that will lower coupling and increase maintainability.
Following ISP leads to better code readability and maintainability: When a client depend on big interface contains many methods, it will be be harder to understand which methods should be used as part of the client scope. While depending on smaller interfaces contains only the required method for that specific client will make it easier to read and understand the required integrations and to write the required code for that specific feature.
ISP Improves code reusability as segregated smaller interfaces lead to smaller modules implementing these interfaces and these tiny modules can be utilized later in different context to do the logic.
Following ISP in some way ensures better adherence to the Single Responsibility Principle (SRP) as a module implement small interface will be doing only one thing, that ensure the Single responsibility Principle is being followed at the same time.
Conclusion:
ISP states a client should not be forced to use an interface with methods it does not need. ISP favors new interface to be created to a new feature instead of adding new methods for existing interface to avoid impacting existing clients. Segregating database read logic from database write logic, is an example of CQRS and ISP at the same time. Following ISP ensures lower coupling, better readability, maintainability, usability and better adherence to SRP.