|

Interface Segregation Principle

Interface Segregation Principle

The Interface Segregation Principle is the next stop on our tour of the 5 solid principles. Thankfully, it’s a pretty easy one to understand. All it means is that a client should not be forced to implement an interface that it will never use. This is the main idea of the Interface Segregation Principle. Just like the rest of the five solid design patterns, the Interface Segregation Principle exists to help decouple modules within software and make the code easier to understand, refactor, and maintain.

Interface Design

At this point, we know how to use an interface in our programs. This is great, but we can still run into problems with interfaces as well. Namely, with the Interface Segregation Principle, we want to be sure that we don’t stuff our interfaces with the kitchen sink of methods. If we add too many methods to our interfaces, they become too fat, and we start to lose some of the benefits of solid that we are trying to achieve. Like always, lets take a look at some code to see what we mean.

To begin, we have a Lumbergh class which has a harass method that depends on an Underling to function. We can see that an Underling should be able to program, filetps, and collate. So far so good we think. Lumbergh is able to sufficiently harass any new underlings that come across his path. Now what happens when Lumbergh needs to bring in some consultants to Initech. How will that play out? Lumbergh should be able to harass Underlings as well as Consultants with equal impunity. Well, maybe we can set up an interface and make Underlings and Consultants implement that interface so that Lumbergh can harass them. Let’s try it out.

We have a small problem. Both our Underling and Consultant classes implement the UnderlingInterface. Consultants however do not collate. The problem is that since a Consultant does in fact implement the UnderlingInterface, and since the UnderlingInterface specifies that we must be able to program, filetps, and collate, then we need to force the Consultant to implement this part of the interface that it will never use. Here is our new updated program, which does work, but it violates the Interface Segregation Principle (Consultant is being forced to implement the collate method).

How Can We Do Better?

lumbergh
The solution to an ISP problem is to divide the interface into smaller pieces. It is ok in fact to have an interface that has only one method. The problem comes in when you have an interface that just has method after method after method after method that one must implement. The more methods that need to be implemented, the greater the chance for ripple effects in your program.

First off, we can break out our UnderlingInterface into a ProgrammableInterface, FiletpsableInterface, and CollatableInterface.

Not Ideal

Better

Now we can update our Underling and Consultant classes to implement only the interfaces that they need to.

The Final Implementation

We’re pretty close to where we need to be at this point but we need to circle back around to the original Lumbergh class. As it stands now, the Lubergh class is going to need to do type checking on the instance it is passed. It needs to check whether it is dealing with an Underling or a Consultant. The reason for this is that Lumbergh can not call a collate method on a Consultant type. Recall that we are not supposed to have to do this! If we need to do type checking to determine behavior, we are likely breaking something in the solid suite of design principles. This means we need one more interface. We will set this up so that no matter what gets passed into the Lumbergh class, only one behavior will need to take place, and that is to answer_to_Lumbergh(). This is how we do that.

Passing in an Underling gives the desired result

Passing in a Consultant also gives the desired result

Interface Segregation Principle Summary

Don’t force classes to implement behavior they will never use. It’s that simple!