

























Published · 7 min read
A wrapper library is a thin layer of abstraction around an existing library, dependency, or functionality. A wrapper library offers a better and cleaner interface or rather hides the dependency or library. Writing a wrapper library can be a hard decision since it requires more work and expands the project scope. On the other hand, it has long-term benefits like better validation, good default parameters, and the ability to replace existing wrapped artifacts. I'd like to discuss some of the aspects of writing a wrapper library in this post.
At its core, a wrapper library is a bet: you trade a bit of upfront cost for future flexibility and control.
Sometimes that bet pays off massively; other times it becomes yet another layer you have to maintain. The real challenge is knowing when a wrapper solves a problem and when it simply adds another one.
Writing Wrapper Libraries
Nowadays most of the projects depend on open source projects a lot. One can't just write wrapper libraries around all 3rd party libraries and dependencies. At the end of the day, writing and maintaining wrapper libraries has its costs and can be a technical debt in the future. A wrapper should solve a real problem, not just satisfy an aesthetic preference for “cleaner code.” Thus, we have to make a call when to write them. I believe the following scenarios justify writing wrapper libraries.
The economy of writing wrapper libraries depends on one shop to another. If you are working in a big shop, it might be easy to decide since you have more people to benefit from the wrapper. However, if you are working in a small shop, writing a wrapper library can be an immense waste of time. So, writing wrapper libraries can be largely about the environment. Nevertheless, I believe one shouldn't write wrapper libraries for the following scenarios.
In short, not every dependency deserves a layer on top of it. A wrapper should reduce complexity, not manufacture new forms of it.
The need for a wrapper already demonstrates its advantages. A wrapper library can give further positive leverage to the project. I'd like to visit some of these extra advantages of wrapper libraries.
In many cases, a wrapper becomes the “gateway” to how your organization uses a dependency and that consistency pays off long after the initial work is done.
I'd like to briefly touch on a practical example where you want to provide a company-wide key/value store infrastructure. There are many technologies to choose like Memcached, Redis, MongoDB, or simply MySQL. We don't want to tie the company to any of the technologies but we also need a solution. In this case, we can simply have an interface for a key/value store as simple as the following.
This is a common situation in larger engineering organizations: different teams experiment with different tools, but eventually someone has to unify the chaos. A wrapper gives you one stable door to walk through, regardless of what sits behind it.
package com.yusufaytas.database;
/\*\*
\* A simple interface for key/value database
\*/
public interface KeyValueDatabase
{
/\*\*
\* Returns payload associated with the key
\*
\* @param key
\* @return payload
\*/
String get(String key);
/\*\*
\* Stores the payload with the associated key
\*
\* @param key
\* @param payload
\*/
void put(String key, String payload);
}
This example is nothing more than a simple interface. You can potentially apply the inversion of control pattern to attach different implementations of the key/value store. In the actual implementations, you can handle the connection to the different technologies. Moreover, you can apply various different configurations options that are relevant to your shop e.g. performance optimizations. The consumer of the wrapper library doesn't need to know anything about the technology stack. The consumer can also easily mock the above interface for testing purposes. The interface can be further improved like adding multi put operations. All in all, the wrapper gives huge flexibility.
The real value shows up months later, when a new storage technology appears or an existing one becomes too expensive or unreliable. Instead of rewriting every call site across dozens of services, you just swap the implementation behind the wrapper. That’s the payoff: freedom to evolve without breaking your entire codebase.
I've tried to explain when it's appropriate to write a wrapper library around a dependency or technology. I've then briefly discussed additional advantages of having a wrapper library as well as a simple practical example. Before rushing into writing one, I highly suggest holding a meeting to discuss the pros and cons.
A wrapper can save you months of pain or create months of unnecessary maintenance depending on why you build it. The point is not to wrap everything; the point is to wrap with intention. If the abstraction simplifies your world, protects you from churn, or gives your team a cleaner way to work, it’s usually worth it. If not, it’s probably just another layer you’ll need to carry.
As with most engineering choices, clarity beats cleverness. Know the cost, know the benefit, and make the decision with your future self in mind.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。