Skip to content

The Art of Integratio

How to cleanly embed external libraries into your own architecture

Green and black plant on a white wall

Photo from Elena Joland on Unsplash

The Invisible Responsibility

Every day we work with code from third parties. What does this have to do with Clean Code if the code doesn't come from us? Surprisingly, quite a lot. It's not about how the external code itself is written, but how we design its usage according to Clean Code principles. Naturally, we can't do without third-party libraries – modern software development would hardly be possible without them.

Strategies for Clean Integration

Here are the most important approaches for clean handling of external code:

  • Tests to validate assumptions

  • Encapsulating and hiding complexity

  • Using the Adapter Design Pattern

  • Defining clear boundaries

  • And additional practices...

From Experimental Usage to Stable Tests

When exploring a new library, we often write a temporary main method with console outputs to understand its behavior. These experiments are frequently referred to as PoCs (Proof of Concept) and are later deleted.

But why throw away this valuable code? Instead, we could write automated tests. With a test runner, we have a perfect environment to execute code and verify our assumptions. This ensures that the third-party code works as expected. Another decisive advantage: when upgrading versions, we can run these tests again to check if our assumptions remain valid. Even simple tests with console outputs are more valuable than deleted code.

Hiding Complexity Behind Domain Abstractions

A classic example of hiding complexity is the use of HashMap. This powerful data structure is often underestimated and in languages like Go, frequently used directly for business logic. You can use the technical API of a HashMap directly in the code:

Map<AutoId, TuvReport> tuvReports = new HashMap<>();
var report = tuvReports.get(id);

Or you can hide it behind a domain-specific class:

class TuvReports {
   public void addReport(autoId, report);
   public boolean hasValidReport(autoId);
   // ...
}

With this approach, you gain a clean, domain-specific interface. We follow the Single Responsibility Principle and make writing tests easier.

The Adapter Pattern as a Bridge

When the interface of a third-party library appears unsuitable or too complex for us, we can implement an adapter. As mentioned in previous articles, API design is a crucial topic. With the Adapter Pattern, we can design the interface ourselves so that it fits logically with the rest of our code. This improves both readability and understanding.

Defining Clear Boundaries

Always set clear boundaries when working with external code. Take the time to consider: when, how, and where do I want to use this code so that my own code continues to clearly represent the core domain? Encapsulate and hide the concrete technologies. Validate your assumptions and expectations through targeted tests.

This conscious design of interfaces to external code is an essential, often overlooked aspect of Clean Code that leads to significantly more maintainable systems in the long run.

Author

Sebastian Bergandy
Sebastian Bergandy