In SOLID, what is the distinction between SRP and ISP? (Single Responsibility Principle and Interface Segregation Principle)

SRP tells us that you should only have a single responsibility in a module.

ISP tells us that you should not be forced to be confronted with more than you actually need. If you want to use a print() method from interface I, you shouldn't have to instantiate a SwimmingPool or a DriveThru class for that.

More concretely, and going straight to the point, they are different views on the same idea -- SRP is more focused on the designer-side point-of-view, while ISP is more focused on the client-side point-of-view. So you're basically right.

It all came from

The ISP was first used and formulated by Robert C. Martin when doing some consulting for Xerox. Xerox had created a new printer system that could perform a variety of tasks like stapling a set of printed papers and faxing. The software for this system was created from the ground up and performed its tasks successfully. As the software grew, making modification became more and more difficult so that even the smallest change would take a redeployment cycle to an hour. This was making it near impossible to continue development. The design problem was that one main Job class was used by almost all of the tasks. Anytime a print job or a stapling job had to be done, a call was made to some method in the Job class. This resulted in a huge or 'fat' class with multitudes of methods specific to a variety of different clients. Because of this design, a staple job would know about all the methods of the print job, even though there was no use for them.

so

The solution suggested by Martin is what is called the Interface Segregation Principle today. Applied to the Xerox software, a layer of interfaces between the Job class and all of its clients was added using the Dependency Inversion Principle. Instead of having one large Job class, a Staple Job interface or a Print Job interface was created that would be used by the Staple or Print classes, respectively, calling methods of the Job class. Therefore, one interface was created for each job, which were all implemented by the Job class.

@ http://en.wikipedia.org/wiki/Interface_segregation_principle#Origin


SRP is concerned with what a module does, and how it is done, disallowing any mix of abstraction levels. Basically, as long as a component can be extensively defined with a single sentence, it will not break SRP.

On the other hand ISP is concerned with how a module should be consumed, whether it makes sense to consume just part of the module, while ignoring some aspect.

As an example of a code that keeps the spirit or SRP, but can break ISP is the Facade pattern. It has a single responsibility, "providing simplified access to a larger subsystem", but if the underlying subsystem needs to expose wildly different thinks, it does break ISP.

That said, usually when a piece of code breaks a SOLID principle, it often breaks the whole lot. Concrete examples that break a specific principle, while preserving the rest are rare in the wild.


Robert Martin tweeted the following on May 16, 2018.

ISP can be seen as similar to SRP for interfaces; but it is more than that. ISP generalizes into: “Don’t depend on more than you need.” SRP generalizes to “Gather together things that change for the same reasons and at the same times.”

Imagine a stack class with both push and pop. Imagine a client that only pushes. If that client depends upon the stack interface, it depends upon pop, which it does not need. SRP would not separate push from pop; ISP would.