← All categories

Structural

How objects fit together: wrapping, adapting and composing them.

Structural problems are about the shape of the code rather than any single algorithm. A vendor library with an awkward interface leaks into every class, a tree of items is handled with different code for leaves and branches, or every combination of features gets its own subclass.

The fix is usually to put a well-chosen object in between: one that translates an interface, wraps another object to add a feature, treats a group like a single item, or stands in for something expensive until it is really needed.

You'll recognise it when

  • Third-party types appear in method signatures all over your domain code.
  • Class names combine two ideas (EncryptedCompressedFile, RedLargeButton).
  • The same recursion over a tree is hand-written in several places.
  • Callers must make several calls in a fixed order to do one thing.

Example

A music player shows lyrics from a vendor whose API uses its own track codes and returns raw text.

Before
class NowPlayingScreen {
    String lyrics(Song song) {
        VendorLyricsApi api = new VendorLyricsApi();
        String raw = api.fetchLyr("TRK-" + song.isrc(), "en-IN");
        return raw.replace("\\n", "\n").trim();
    }
}
// ...and the same three lines again in the karaoke screen
After
interface Lyrics {
    String forSong(Song song);
}

class VendorLyrics implements Lyrics {
    private final VendorLyricsApi api = new VendorLyricsApi();
    public String forSong(Song song) {
        return api.fetchLyr("TRK-" + song.isrc(), "en-IN").replace("\\n", "\n").trim();
    }
}

class NowPlayingScreen {
    private final Lyrics lyrics;
    NowPlayingScreen(Lyrics lyrics) { this.lyrics = lyrics; }
    String lyrics(Song song) { return lyrics.forSong(song); }
}

Why it's better: Only one class knows the vendor exists. Switching vendors, or using a fake in tests, means writing one new class instead of editing every screen.

Ideas you'll practise

AdapterBridgeCompositeDecoratorFacadeFlyweightProxy

Problems 17