Design Pattern Principles - Interesting Interfaces

Interfacing with Interfaces

One of the first lessons that the design pattern book threw at me was to "Program to an interface, not an implementation".  Having more experience under my belt, I've begun to notice the importance of decoupling requirements and code, such that we can create well-defined, manage-able code.

So what does this mean to me?  For a long time, interfaces to me was more boilerplate code that I would have to set up to define an object that I already had.  But as I grew to work on more and more complex systems, its been a godsend to be able to use interfaces to dynamically swap components at run time, and to allow our architecture to be more flexible and robust.

How do I use it?

One of the greatest uses of interfaces is to facilitate the contract / handler pattern that allows us to decouple our implementation of a service, and allow us to swap in any other service that follows the same spec.

Designing Your System for Change

Let look into this by looking at an example problem and seeing what we can make from this.

Problem: Your building a ride sharing app and you need to implement a service that can direct drivers from a pickup location to the passenger's destination.

At first it seems pretty straight forward, if you really wanted to you could straight up integrate this with Google Maps and be done with it.  You can go along and implement your app based on Google's available APIs and probably get something working fairly quickly.

Now we introduce an issue (because if I learned anything, no service comes without issue).  Lets say Google has decided it doesn't believe your application is following their TOS and will halt your service next month.

Well that sucks.  Now we have to go back and define what belongs to their service, and what belong to your application.

Lets take the time to rethink how we can turn this situation around and learn from the past and implement this the right way.

First, lets take the requirements that we previously had for Google Maps and right down the necessary functionality we expect from this service.  1. Query Address (string) 2. Route(point1, point2), etc.  From this we define our interface with these requirements mapping to a function.

Next we check what services we can use to replace this, we can pick from Bing, Yahoo, or some other provider.

Next we create our implementation portion using the service we have chosen.  Note we should be able to independently code this service from the rest of the application, all by following the interface and limiting dependencies on the application itself.

After the implementation is complete, we can start hooking up our service to the service contract interface we have created, and there we have it.  A nice decoupled design.  In the event that we would need to switch to another provider, then we already have the contract in place to determine what we need to implement, and can swap out components as needed.

Support for Multiple Services

Another Use Case: Using the same example of a ride sharing app, lets say that our app has taken off, and now many companies want to be able to utilize our platform.  But with the catch that they have their own set of relationships that they prefer to use a different vendor for maps and directions.  This enables us to support the swap-ability between different handlers that satisfy our contract, without breaking any implementation.  We have the ability to assign the handler at run-time, based on the client requirements.

TL;DR

So, interfaces can we pretty cool.  It lets us decouple our code from specific implementations, and allows us to easily change between alike services and support multiple at run-time.  Would Recommend!

Comments

Popular posts from this blog

Uncle Bob's Clean Architecture

C4 Model: Describing Software Architecture

Running RabbitMQ with Docker