Interface Segregation Principle (SOLID 4/6)

Clients should not be forced to depend upon interfaces that they do not use. (Robert C. Martin)

That is the definition of the interface segregation principle (ISP). This needs some explanation like other SOLID principles has had in this series. I will explain this first with an example of violating it.

Example of Violating ISP When Adding New Method

Suppose we have an ICar interface with few methods:

public interface ICar
{
  void StartEngine();
  void StopEngine();
  int GetSpeed();
}

Some time passes and we make some classes that implement ICar interface. Then comes a day when we implement Ferrari and Porche classes with a turbo. Because we have two classes with turbo, we decide to add new Turbo method to the ICar interface:

public interface ICar
{
  void StartEngine();
  void StopEngine();
  int GetSpeed();
  void Turbo();  // ISP violation!
}

But that forces us to implement Turbo method to slower cars also. Slow cars are now forced to implement Turbo method that they do not use. And that violates ISP.

ISP Equals Small Interfaces

Let’s try to fix the ICar interface to apply ISP. The easiest way is to extract Turbo method to its own ISportsCar interface:

public interface ISportsCar
{
  // moved from ICar
  void Turbo();
}

public interface ICar
{
  void StartEngine();
  void StopEngine();
  int GetSpeed();
  // Turbo moved to ISportsCar
}

Now our slower cars don’t have to implement the Turbo method but sports cars, like Ferrari and Porche, can implement ISportsCar interface and Turbo method. This doesn’t violate ISP because no car isn’t forced to implement Turbo method. But still, they can implement it via ISportsCar if they want. In this example we followed a rule for ISP:

Many client specific interfaces are better than one general interface.

Practically ISP means that use small interfaces with even only one method rather than one fat interface with many methods. Then clients of interfaces are free to choose what interface(s) they want to use and not forced to implement methods they don’t even need (like Turbo method for a regular car).

In his Encapsulation and SOLID Pluralsight course, Mark Seemann called these fat interfaces header interfaces because they look like C++ header files. And small interfaces with just few methods he calls role interfaces. Role interface name comes from because the interface has a specific role which could be just that one method.

How to Create ISP Friendly Interfaces? The answer to this question is little tricky: don’t create them, let clients who will use the interface, define it. In this way, there won’t be methods in the interface that the client doesn’t use.

Make fine grained interfaces that are client specific. (Robert C. Martin)

Helps With Liskov Substitution Principle

If we follow ISP it also helps us to follow the Liskov substitution principle (LSP). Because if we follow ISP, then we won’t have any classes that can’t implement some method of the interface. And if we always implement all methods of interface it will help also to follow LSP.

More clearly it is in vice versa. If we violate ISP and have some method in the interface that all clients won’t use, then we are forced to for example just throw NotSupportedException in those subclasses. And as we saw in the previous LSP blog post it will violate also LSP.

Helps Also With Single Responsibility Principle

If we define thin interfaces as ISP suggests, each interface will have only one role. That reduces changes to those interfaces, and probably also to classes that implement it because there is now only one reason to change them. Doesn’t this sound familiar? Yes, it is the single responsibility principle (SRP) that I wrote a blog post earlier in this series. ISP reduces modifying multiple files like SRP.

Similar to the Single Responsibility Principle, the goal of the Interface Segregation Principle is to reduce the side effects and frequency of required changes by splitting the software into multiple, independent parts. (Thorben Janssen)

Conclusion

ISP is quite powerful SOLID principle because it helps to follow even two other SOLID principles: SRP and LSP. In my opinion, especially the relationship with SRP makes it a principle worth to follow.

In one way ISP is just like following clean code: create small interfaces/classes. Even if I really like clean code, I have had my suspicion about one method interfaces. After writing this blog post I understand the reason for them better.

But I have doubt if I am able to follow it by thinking from client’s perspective and let client define the interface it uses. Next time when creating an interface, I will read this blog post and make it apply ISP and “finalize” my learning about ISP.

Sources and Influences

Blog Posts in This Series

5 thoughts on “Interface Segregation Principle (SOLID 4/6)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s