ADAPTER / PRACTICE
One player.
Different library languages.
You met Adapter through weather data. Now connect an older audio library to an existing player.
YOUR BRIEF
The music fits. The interface does not.
The player calls load(id) and expects a title, a duration in seconds and a playable boolean. LegacyAudio only offers findTrack(id), returning track_name, length_ms and access_code.
The library cannot be passed directly to the player. Preserve its data's meaning while making it fit the player's contract. Unknown codes must cause an error rather than an invented permission.
The player already has a contract
type Track = Readonly<{ title: string;
durationSeconds: number; playable: boolean }>;
interface TrackSource { load(id: string): Track }
function readPlayer(source: TrackSource, id: string): Track {
return source.load(id);
}Keep this client unaware of vendor-specific units, method names and access codes.
01 / ASSEMBLE
Translate at the boundary.
Choose where the vendor rules belong, then preserve the meaning of its duration and access fields.
Your assembled code
TypeScript preview. Highlighting follows the selected execution.
Target · what the player understands
type Track = Readonly<{ title: string; durationSeconds: number; playable: boolean }>;
interface TrackSource { load(id: string): Track }Existing library · incompatible method and data
type LegacyTrack = Readonly<{ track_name: string; length_ms: number; access_code: string }>;
class LegacyAudio {
constructor(private id: string, private track: LegacyTrack) {}
findTrack(id: string): LegacyTrack {
if (id !== this.id) throw new Error("Track not found");
return this.track;
}
}Your translation boundary
// Choose all three pieces to assemble the translation.Player · target interface
function readPlayer(source: TrackSource, id: string): Track { return source.load(id); }Setup · supply the selected source
// Complete the assembly before loading a track.02 / RUN & OBSERVE
Same track. A different interface.
185000 milliseconds and ok should become 185 seconds and playable = true.
Request goes down ↓ · Translated data returns up ↑
source.load("track-01")Expects title, durationSeconds and playableNo track loaded yet
load(id) → findTrack(id)Method, fields, units and code meanings meet here.
{
"track_name": "Evening loop",
"length_ms": 185000,
"access_code": "ok"
}Choose an assembly, then watch the request and response cross the interface boundary.
Data and design feedback will appear here.
- ○ Load a playable track — run to verify
- ○ Load a blocked track — run to verify
- ○ Reject an unknown access code — run to verify
Each test uses a fresh local library. No audio plays and no external service is contacted. For these known sample shapes, the adapter preserves titles and IDs, converts units, maps known codes and rejects unsupported ones.
03 / TRANSFER THE IDEA
Another library wants to connect.
ArchiveAudio exposes fetch(id) and returns name, duration_seconds and can_play. Its values already use seconds and a boolean; its method and field names still do not fit TrackSource.
Connect it while keeping the same player. Which edits are needed?
First pass all three legacy-library cases with the same assembly.
Compare with a complete solution
No timer and no attempt limit. Try another assembly, use a hint, or reveal the answer when it helps.