DEV Community

Discussion on: In Defense of Clean Code: 100+ pieces of timeless advice from Uncle Bob

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thanks for the thoughtful comment!

I've seen this go both ways, good and bad. An interesting result of not using a wrapper API around a third-party API is that if you don't do it, you're likely to stay stuck on that library forever (which might be ok in some cases!).

I've seen this happen in a few companies now with things like date libraries (Moment.js, Day.js, date-fns, homegrown library, etc.), currency-formatting libraries, and XHR libraries (jQuery ajax, axios, etc.). The third-party code gets so interwoven with all the other source code that it becomes impossible to migrate away from one library and onto another. Or, not for the faint of heart, months of effort to migrate.

I think the lessons I've learned from those experiences line up pretty well with the advice in Clean Code, which would be to either 1) use a thin API wrapper over the third-party API, or 2) try to limit how much of your codebase knows about the third-party library, since that will make swapping technologies easier. And those two ideas are interesting because the first idea is really just a solution to the second idea! So however you approach it, the second idea seems to be the core principle here.

It's definitely exciting to see the native APIs get better where all three of the examples I gave will soon become a non-issue!

Collapse
 
mindplay profile image
Rasmus Schultz

Libraries with types tend to get very interwoven - function libraries such as date-fns generally do not. There is absolutely nothing won by wrapping somebody else's function in your own function - it's the exact same situation, now you're just coupled to that instead. Switching from a function you wrote, or from a function you imported, is the exact same amount of work.

Even with some classes, wrapping them might not mitigate the problem and can actually make matters worse - it really depends... See this:

youtu.be/tqqH_Ib_gDc

Thread Thread
 
thawkin3 profile image
Tyler Hawkins

I watched his video, and it's interesting, but I don't think his argument is quite right. He basically says throughout the video not to use abstraction because you're going to do it wrong. So he's really arguing against doing abstraction badly.

Some of his key points were:

  1. If you write an abstraction layer, you're going to start leaking very specific functionality from the specific third-party library into the rest of your codebase.
  2. If there is a breaking change in the third-party library's API, then there will be a breaking change in your abstraction layer, where they have to be updated in lockstep.

Both of those ideas aren't criticisms of abstraction though, those are criticisms of doing abstraction badly.

To solve the first problem, just... don't add the third-party library's implementation details into your abstractions's interface. Leaking the implementation details defeats the whole purpose of abstraction.

For the second problem, it may be true in some cases that a breaking change in the third-party library's API will cause a breaking change in your abstraction layer, but it's not necessarily true. It may be very possible to write a good abstraction that can handle the third-party library's breaking change while not actually changing the interface that your abstraction creates. That's the beauty of abstraction: the rest of your app doesn't know about the changed implementation details.

His last point is great though about abstraction being hard to get right and that getting the interface right the first time is important.