Interface Segregation Principle

Before the Kurukshetra War, Lord Krishna had a conversation with Arjuna, one of the things he said:

Therefore I tell you: be humble, be harmless, have no pretension, be upright, forbearing, serve your teacher in true obedience, keeping the mind and the body in cleanness, tranquil, steadfast, Master of ego, standing apart from the things of the senses, free from self; aware of the weakness in mortal nature, its bondage to birth, age, suffering, dying;

One of the wonderful results of writing about right coding and better code philosophy is the oportunities it provides to be humble. I frequently write bad code and don’t follow the principles I know to be correct.

First, let’s define the Interface Segregation Principle (see the excellent Uncle Bob Article)

Clients should not be forced to depend upon interfaces that they do not use.

Frequently, when you look at C# code, you’ll see interfaces defined that have a lot of members defined (Try implementing a Forms Authentication Provider and you’ll see what I mean!). The downside of this is that it’s confusing for the client to know which methods to use. It also forces each alternate implementation of the interface to implement a bunch of methods that maybe are not relevant (in the example of forms authentication, you have to handle email addresses even if you only want to implement a username/password).

The Interface Segregation Principle suggest sthat our interfaces should be simpler and more focused, supplying only the members needed for a specific use. If one object implements more than one interface, that’s fine, but an object that supports multiple uses should provide targeted interfaces for each of those uses.

Let’s look at how I violated this principle in the my UI code:

Each endpoint on the Login Controller has a corresponding method on the interface. It’s impossible to change our just one implementation. You have to provide a replacement for the whole login service in order to implement any changes.

The fix is easy:

And suddenly, each individual service can be swapped out separately. It’s also much easier for me to refactor my LoginService implementation to comply with the Open-Closed Principle and Single Responsibility Principle.

There is always room for better code, and the SOLID principles are wonderful tools in learning to write better patterns.