Saturday, November 14, 2009

SRP subsumes ISP

Yesterday I listened to a friend who held a presentation about the SOLID principles. You know, the five principles in object oriented design that Uncle Bob put together.

Single Responsibility Principle
Open/Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle

If you're not familiar with them you should read up right now. Here's a good place to start.

Anyway, when my friend reached the I of SOLID it struck me that ISP is only interesting if you've violated SRP to start with. I've always thought of it as a refactoring pattern, but all the definition says is that "make fine grained interfaces that are client specific". Adhering to the SRP it would be difficult to make interfaces any other way... I decided to confront Bob with this, and he seems to agree:

I asked:
would you agree that ISP is self-fulfilled if SRP is used? ie, ISP only has a value on its own when working with bad design?

And he replied:
Strictly speaking, SRP subsumes ISP. The problem is you can't always be as strict about SRP as you'd like.

So, ISP is mainly an option if you fail to design by the most important principle. But as Bob states, it's not at all uncommon that you do that so there's still value in the principle.

Also, I think ISP is a great principle when dealing with legacy code. If you have a huge class it may be both difficult and very time consuming to refactor it to meet SRP. Here I use ISP as a lightweight SRP, creating the interfaces that I'd like the objects to be in a good SRP design and then have the same class implement them all. It takes virtually no time, and then I can start writing good code from that point on. It also helps me if I want to refactor out one of the many parts this legacy class may contain.

If I'd end up with some kind of conslusion it would be that you shouldn't think much about ISP when designing new software, but it's a great principle for refactoring!