Abstraction manages complexity by placing lower-level implementation details inside reusable blocks, treating them as black boxes, and composing them into higher-level operations. This approach supports system structure, but deciding the right boundaries remains a central design responsibility. section 1.1.2
Effective abstractions balance simplicity with practical control:
- Expose a small, predictable interface rather than every handler and parameter. section 13.1
- Avoid leaky abstractions that expose too many implementation details. section 13.1
- Hide complexity behind reasonable defaults, while allowing overrides for customization and debugging. section 13.1
- Reconsider heavyweight upfront structures when changing requirements make detailed plans inertial or bureaucratic. section 1.1.2
A configurable prediction interface
A prediction API can expose predict(features, time=None, seed=42), supplying a current time by default while retaining explicit controls for reproducibility and debugging. A model version can also be selected during initialization without exposing model-loading internals. section 13.1
Figure 13.1 Overconfiguration vs. underconfiguration
Compare overconfiguration with underconfiguration when deciding which implementation details and controls an interface should expose. section 13.1














