The Clean Boundary
When you use a third-party API (a Map, a logging library, an HTTP client) directly throughout your codebase, every change to that API affects your entire system. Instead, wrap it in a class you control. The wrapper speaks your language, and you can replace the underlying library in one place.
Raw dict leaking everywhere
sensors = {}
sensors["t1"] = new Sensor("t1")
temp = sensors["t1"].read()
sensors.clear() // intentional?
remove sensors["t1"] // scattered 40+ files
Wrap it — you control the interface
class SensorRegistry:
sensors = {}
function register(sensor):
sensors[sensor.id] = sensor
function reading(sensorId):
return sensors[sensorId].read()
function remove(sensorId):
remove sensors[sensorId]
Learning Tests
When adopting a third-party library, write focused tests that explore its behavior — not to test the library (it has its own tests), but to document your understanding of it. These tests become a safety net: if the library upgrades with a breaking change, your learning tests fail first, before your production code breaks.
// Learning tests for a fictional cache library
function test_cache_returns_null_for_missing_key():
cache = new Cache(maxSize: 10)
assert cache.get("missing") == null
function test_cache_evicts_oldest_when_full():
cache = new Cache(maxSize: 2)
cache.set("a", 1)
cache.set("b", 2)
cache.set("c", 3) // "a" should be evicted
assert cache.get("a") == null
assert cache.get("c") == 3
function test_cache_ttl_expires_entries():
cache = new Cache(maxSize: 10, ttlSeconds: 1)
cache.set("key", "value")
wait(1.1 seconds)
assert cache.get("key") == null
Using What Doesn't Exist Yet
Sometimes you need to integrate with a component that hasn't been built yet. Define the interface you wish you had, write your code against it, then build an adapter when the real thing arrives. This lets both teams work in parallel and keeps your code clean regardless of the external API's design.
// ✓ Step 1: Define the interface you wish existed
interface Transmitter:
function transmit(frequency, stream): void
// ✓ Step 2: Build against your ideal interface
class CommunicationController:
transmitter = null
function send(data):
transmitter.transmit(COMM_FREQUENCY, data)
// ✓ Step 3: When the real API ships, write one adapter
class RealTransmitterAdapter implements Transmitter:
realApi = null
function transmit(frequency, stream):
realApi.sendOnFreq(frequency, stream.toBytes())
Code Challenge
Wrap the Third-Party Map — the raw Map is spreading everywhere. Wrap it with intent-revealing method names.
Key takeaway
You don't own third-party code. Wrap it at the boundary — your domain speaks your language, not theirs.