Interfaces are Connectors

For a long time, I didn’t get interfaces.

I am referring to interfaces as programming constructs in static languages like Java, C# and C++[1].

I thought it was weird to have interfaces in code. Why use an interface when I have the actual class? Why should I hide it behind an interface? What is it with that?

Seasoned developers may chuckle at my junior developer’s naivete. Many programmers, not unlike my past self, do not have a full grasp on interfaces and how they help create well-thought-out system design. My hope with this article is to shed a little light on interfaces.

Yes, Interfaces are Connectors.

Like a power socket or the towbar on a car are real-world examples of connectors, too.

A power socket represents a universal connector to electricity. You may use a power socket to ‘extend’ the functionality of your home with an electric appliance — like a toaster, microwave oven or computer. As long as your device has the matching, male plug at the end of its power cable, you can plug it in. Now it can receive electricity and fulfil its function.

In our homes, a power socket represents an ‘interface’. Our electric devices must ‘implement’, or fit, this interface for them to connect.

To illustrate further, let us invert the power socket solution in a thought experiment.

Assume that, appliances are connected via fixed power cables. When you want to move the toaster, you’ll have to book in your electrician, wait a couple of weeks for them to turn up, and then they’ll rewire it at another location — for a $300 fee.

This arrangement would not be helpful. It might work for a while, but changes are difficult and expensive to implement.

Similarly, most of us have been in the unenviable situation when a foreign-bought phone charger could not be plugged in at home because it had the wrong plug. In software lingo, the device implemented the wrong interface.

Ok”, you say, “I can see why it is useful to have a universal connector on my home for power. I have lots of electric devices that I use. Being able to plug them in everywhere is great. But how does this apply to software and my code?

Interfaces in software perform a comparable function — they extend the system in a pluggable, modular manner.

Ok, an example is in order.

Let’s say that we want to give ourselves the ability to switch databases easily.

Why would this be useful?

Well, we may find that the original database technology does not scale.

Why didn’t we pick a database that scales well beforehand?

Because nobody knows the future. Requirements change. Use cases that we thought would be popular weren’t. Consequently, the actual database usage profile is different from the anticipated one — the chosen database technology is not optimal and, if possible, ought to be replaced.

Therefore, would it not be useful to design our system in such a way that makes it possible to unplug an entire subsystem and plug in a different one? We would retain options with such system architecture.

Yes, I think this would be useful.

Architect your system to give yourself options.

Let’s return to our database pluggability example.

Below, we have an interface for data access. It has a method to retrieve a list of customers from the given database.

Initially, say, we are using SQL Server as our database technology. Here is the implementation of the IDataAccess interface for SQL Server.

Now, if we wanted to change the database from SQL Server to MongoDB without any rework but just unplugging SqlDataAccess and plugging in a new implementation of IDataAccess for MongoDB then we could do this. Here is the MongoDB implementation code:

Imagine that — plugging in a whole new database without having to make changes in the business logic component of the application code at all!

When you achieve this and get to use it, it’s a kind of magic.

That is what interfaces are about — providing the ability to create and connect modular systems!

Conclusion

We discovered that the primary purpose of the interface construct is to allow us to write pluggable, and therefore easy-to-change, software. Everyday experiences of interfaces, like power sockets, also allow for the extension of our homes with electric devices. Software interfaces provide the same ability to switch application functionality.

[1] C++ doesn’t have interfaces per se. A functional equivalent is an abstract class with only pure virtual functions.