Jul '17


Decoupling Yourself From Dependencies

I've been working on a project for my EVE Online corporation building a web application with tools to help optimize industry game play. I decided to use Go for this project, for no reason in particular. This post is mainly targeting Go codebases, but the general idea is should be familiar and is interesting to consider, regardless. That is:

How can you limit the ways a particular dependency can affect your project?

For an example, imagine your application needs to send email messages. You could easily use the net/smtp package from the standard library throughout your project. But this would introduce a tight coupling with the un-customizable standard library; you wouldn't have a place to add or extend the functionality.

Instead, create a package in your project that acts as an adapter between the library and your project. This allows you to explicitly section off where and how you use that library's API — you only implement what you need, and you can customize that to fit your application. This package defines the API in which the rest of your application uses the functionality you're wrapping.

In our example above, you might imagine a Sender type in the package mail. A Sender is initialized with parameters for the SMTP connection and then provides an interface suitable for the rest of your application. It additionally provides padding should the library ever have a backwards-compatibility break — you'd only have to fix the break in the mail package.

I'd mention one other reason: in the unlikely event that you need to fully replace the library you're wrapping, then this pattern might be very beneficial.

But consider the drawbacks

Overly granular packages are somewhat frowned upon in Go as they can make a project needlessly complicated. If the component in question is used all over the application, then the benefits for having a wrapper increase. It would be rather pointless, however, if that component were only used in one other place. A digression for another time.

The adapter pattern, so what?

Yep, that's all this is. But it doesn't require classical interfaces or objects or inheritance at all. I just think it's interesting that the same patterns can be useful in many different contexts.

Anyway, so long.




No comments yet! Say something.