Deep Modules

Categories
Complexity
Sources
A Philosophy of Software Design

A module is deep when it offers a simple interface over a powerful implementation. Depth is the ratio of functionality provided to interface exposed: the best modules hide a lot behind a little.

Why it Matters

A module's interface is a cost paid by every user; its implementation is a cost paid once. Deep modules maximize the benefit (functionality) relative to the cost (interface), which is how modular design actually reduces complexity rather than just redistributing it.

Signals

  • A short, stable interface that rarely changes even as the implementation grows.
  • Callers accomplish a lot without knowing how the work is done.
  • The inverse, a shallow module, has an interface nearly as complex as its implementation, so it provides little abstraction for its cost.

Benefits

Each interface a developer learns unlocks significant capability. Fewer, deeper modules mean fewer interfaces to understand and fewer places for complexity to leak across boundaries.

Risks

Over-decomposition into many tiny classes/methods (the "classes should be small" reflex taken too far) produces shallow modules and more interfaces. Splitting a module can increase total complexity if it forces callers to manage the interaction.

Tensions

The advice to keep components small conflicts with depth: more, smaller units mean more interfaces. Depth favors fewer, larger units, bounded by the need to keep each implementation comprehensible.

Examples

A garbage collector exposes essentially no interface yet does enormous work: maximally deep. A wrapper that just forwards arguments to another call adds an interface while hiding nothing: shallow.