The Interface Segregation Principle states that no client should depend on methods that it does not use.
In layman terms, what this principle iterates is that you only have to make public that which is essential to the core of your application. You can think of it like this:
You’ve been hard at work all day long. Come 5 O’clock and you and your favorite colleagues decide that a well deserved break is in order. And to make it all the more rewarding, you decide to add a nice fulfilling meal on top of it.
So you make haste to one of your favorite restaurants, a chic, Lebanese cuisine centered, comfy cozy joint right around the block from your office.
You go inside, the waiter seats you, passes you menus and states that he’ll be back shortly for your order.
You choose a delicious rack of lamb with a side of aromatic basmati rice paired with a nice glass of red wine. Your colleagues order similar dishes and all of you place your order. You wait while having a nice chat discussing work or hobby related topics.
45 minutes later the waiter brings your order and all of you dig in. Come the end of your stay, you pay and all of you hop off merrily on your way.
In this specific scenario an interface segregation has been applied. More exactly, the only business related logic that was made public to you – the client – were the menu options. And everything worked out great.
Now imagine that were not the case. In this more “explicit” scenario the waiter gives you a dictionary thick menu and for you to place your rack of lamb order you had access to more private methods like such: slaughter lamb, drain blood, butcher carcass, pay butcher x amount per pound, separate cuts, purchase rice, purchase condiments, pay y amount for each; then pay rent, agree on utilities contract, fire up stove, cook meat, cook rice, add condiments, plate food and serve dish.
If you haven’t yet lost your appetite at slaughter lamb, then you must have been particularly hungry.
In reality, what you – the client – only care about is: view options, place order, wait for order and pay bill. That’s it, and that should be the only thing you should have access to.
Now although you understand that behind the magic that happens between you placing an order and you receiving that order are several more steps, you have no authority on how they are made, nor should you. It means that they are of no interest to you, and as such should be kept hidden.
In programming this relates to the segregation (or separation) of public and private interfaces. If you haven’t yet read the post on Setting Up Good Interface Design, do so now.
You offer a few core functionalities as the base of your application, the things pertaining to your business logic end of the code – and these should be part of your public interface. All the other methods and code bits are just instruments necessary to get you to your destination – and these should be part of your private interface. As such you understand that the private parts may change in time. Thy are less dependable and should be “kept secret”.
As with all programming principles and paradigms, some (or even most of them) you already use – knowingly or unknowingly. The secret to being a good software developer is learning – through practice and experience – to distinguish the patterns that apply for each principle or guide-line in specific scenarios.
Case in point, you cannot successfully apply the Interface Segregation Principle all on it’s own without touching on other SOLID principles or paradigms. For example, an even worse situation then the one in which you knew how the restaurant operates and as such “knew to much about other objects” is the inevitable case in which you decided “how the lamb should be slaughtered” (humanely of course), how the meet should be cooked or worse yet, you decided to take a trip into the kitchen to supervise and give pointers. If you think this is bad enough, imagine that you and all your colleagues had placed the same order, took a trip to the kitchen and expected different results. One wanted it baked, another grilled, one chose stewed etc. You had conflicts.
Speaking of conflicts, I spoke in the title about keeping the Wife public while the Mistress private. If you are curious, I will further illustrate this scenario in a coding example in a later post, but by know you should understand that unless the Wife also uses Mistress (yeah, in your dreams) the less these two know about each other, the better.
If this sound familiar yet then by now you understand that by separating the interfaces you do more than just that. You :
- Declare with confidence which bits are stable and dependable (the public interface).
- Which bits are susceptible to change and as such are not dependable (the private interface).
- Decouple your code by applying the Law of Demeter (LoD). You know waiter and his underlying purpose of take_order, but you do not know cook nor his prepare_food.
- Apply the Single Responsibility Principle, since every object is limited in tis choices and can only really do one thing: You place_order, The Waiter takes_order, and the Cook prepares_food. And they are limited in choices because they are limited in their knowledge of other objects. They are decoupled.
And you Don’t Repeat Yourself. By acting DRY you apply the essence of SOLID design principles and create good, scalable and dependable code. But more about the DRY principle in a later post.
Great article. And I appreciate how you tie them to other SOLID principles.
I always thought ISP was about ensuring that a class didn’t have to implement functions it did not care about. For instance, if your interface had 3 methods defined, but some classes really only need 1, then ensure that clients didn’t have to implement the other 2. And in order to fix that, compose a class from separate interfaces instead.
“Witch bits are susceptible to” should be “Which bits are susceptible to”. Unless their wicked bits with evil potions. 🙂