IMagic – The power of interfaces

This one talks about the power of Interfaces, and how polymorphism can make things highly flexible and decoupled. Interface is a simple view of your class-to-be to the outside world, a perfect form of abstraction. Wikipedia says

A protocol or interface is a common means for unrelated objects to communicate with each other. These are definitions of methods and values which the objects agree upon in order to cooperate.

Lets take an example for better understanding. Assume, I am creating my good old calculator again.

JavaScript

1

2

3

4

5

6

7

8

9

publicclassCalculator{

publicButton[]Buttons;

publicDisplayPanel UserDisplay;

privateint_operand1;

privateint_operand2;

privatechar_operator;

privateintcalculate(){

}

}

Being poor, I can’t afford any staff to work on my jazzy calculator. I have come up with all my classes and stuff, but can’t start working on my calculators logic, as my Calculator has an object of type DisplayPanel, and I will have to complete the implementation of this class in order to use it in Calculator otherwise my compiler will simply keep complaining and won’t let me proceed. But Calculator seems far more interesting to start with than DisplayPanel. So what do I do? You may say, I will write the DisplayPanelclass and leave all the functions blank!! Smart 🙂 What about the non-void functions if any? You would return some random value based on the type of the return type of the function. Well, why do all this? I would simply go ahead and replace the type of UserDisplay from DisplayPanel with its interface (say IDisplayPanel).

JavaScript

1

2

3

4

5

6

7

publicinterfaceIDisplayPanel{

voidShow(stringdisplayString);

}

publicclassCalculator{

publicIDisplayPanel UserDisplay;

//...

}

Now, I can bindass go ahead and keep calling UserDisplay.Show(), without the trouble of keeping my compiler happy. This code will build with no compile errors, but will fail at run time since you can only call a function on a solid class instance, not interfaces. So how do I know if what I have written so far works or not? Well unit tests with mocking is the answer, I would like to defer this topic for a post in the near future.

After showing my Calculator idea to some biggy investors in the silicon valley, I manage to get funding to hire 2 assistants. Yippee, now I can get some work on the DisplayPanel started with their help. I assign this task to Bluto, one of my assistants. While my other assistant, Popeye, has no work for the time being and is enjoying spinach with Olive 🙂 Brutus thinks he has come up with an exciting implementation and even I have finished working on my Calculator

Time to merge the code gentlemen!

Scary??? No, all that we need to do is assign the UserDisplay to a concrete class, the one Brutus wrote, before I make any call to any of its methods. Best place is in the constructor.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

publicclass DisplayPanelByBrutus:IDisplayPanel{

voidShow(stringdisplayString){

//...

}

}

publicclassCalculator{

publicIDisplayPanel UserDisplay;

publicCalculator(){

UserDisplay=newDisplayPanelByBrutus();

//...

}

//...

}

Great !!! All works fine, but….. Brutus, as dumb as he is, came up with a very lame and irritating implementation of the IDisplayPanel, this one throws a big message box (IE Style) to the user with the content to display, that too every time I press any button on the calculator :'( !! Popeye, meanwhile knew how pissed I would be, and had already prepared another implementation that he was ready to show me. Better than I thought, a sleek panel on top of all my calculator buttons to immediately show what key the user presses and the result too. Yes, the windows calculator is a complete rip off of Popeye’s version. Wow!!! Totally wanted to get this into my production code. But code change again!!! Well this time it’s just a one line change, in fact half a line.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

publicclass BakwasDisplayPanelByBrutus:IDisplayPanel{

voidShow(stringdisplayString){

//...

}

}

publicclass AwesomeDisplayPanelByPopeye:IDisplayPanel{

voidShow(stringdisplayString){

//...

}

}

publicclassCalculator{

publicIDisplayPanel UserDisplay;

publicCalculator(){

//UserDisplay=new BakwasDisplayPanelByBrutus();

UserDisplay=newAwesomeDisplayPanelByPopeye();

//...

}

//...

}

Hope the IMagic got through to you by now. Interfaces allow us to decouple our implementations. You are not bound to someone’s speed of coding. Before you get working on your code that uses someone’s code all you need to do now is just sit together, analyze and agree upon an interface that you both are comfortable with, and both can proceed peacefully and independently. Also, this allows easy migration from one implementation to the other, imagine if you had to change the implementation in case of concrete classes, you would change the body of all your functions, and if the new implementation turned out to be worse, you don’t even have the old code to rollback to, unless you have taken some backup, which again would be tedious to some extent. Here all you do is just change the constructor, and still both the implementations co-exist, this gives the user a choice as well.

Another, in my opinion more powerful, advantage that interfaces give, is when we are actually dealing with enterprise software that depend on third party pluggable code. (You may want to skip to the end, if you are an absolute beginner). In a more complex aka real-world application, you may not have all the code in the same file, in fact not even in same project. Here all you would have is the interface, which would generally be shared across projects. In such cases, your Calculator class won’t even know there is something called AwesomeDisplayPanelByPopeye, only the classes using this calculator may know about it. Hence your statement

JavaScript

1

UserDisplay=newAwesomeDisplayPanelByPopeye();

Will give a compile error as the class AwesomeDisplayPanelByPopeye is not present in any of the referenced libraries. In such cases, or even otherwise, a concept named Dependency Injection comes into play. In our case, the Calculator is dependent on IDisplayPanel, we don’t want the calculator to decide which implementation of this interface to use, but let the user of the Calculator decide it instead. This is done in various ways, one of them is through the constructor. We remove the default parameter-less constructor, and instead use a constructor that takes an object of type IDisplayPanel, and assign this object to our UserPanel as follows.

JavaScript

1

2

3

4

5

6

7

8

publicclassCalculator{

publicIDisplayPanel UserDisplay;

publicCalculator(IDisplayPanel someDisplayPanel){

UserDisplay=someDisplayPanel;

//...

}

//...

}

Now, your code is truly agnostic of the implementation of IDisplayPanel that it will use. You can now have n different Calculators from the single Calculator that you wrote. Today’s world is all about choices, more choice you give, more people will use it 🙂

He has been a preacher of Highcharts since he got acquainted with it at work & now attempts to help developers on Stack Overflow with his little knowledge. He occasionally blogs about Highcharts & has been a reviewer of the Highcharts Cookbook recently.

Jugal relishes playing Ping-Pong, solving puzzles or trying his luck at a Bowling alley. To know of what he learns, experiments and explores visit http://jugal.me/ or follow his blog, A Humble Opinion, @ https://ahumbleopinion.com/