Skip to content

02 — Modularity & Information Hiding

Driving question: What should a module hide, and from whom?

Learning objectives

  • Explain information hiding as hiding design decisions likely to change.
  • Separate interface size from conceptual stability.
  • Identify leakage of volatile decisions across module boundaries.
  • Reason about modularity at class, package, component, and service levels.

Information hiding

A module boundary is valuable when it prevents a change inside the module from forcing unrelated clients to change. The hidden information may be:

  • a data representation;
  • an algorithm;
  • a storage mechanism;
  • a protocol;
  • a policy;
  • a vendor API;
  • a scheduling/concurrency decision.

Example

interface PriceCatalog {
    Money priceOf(ProductId id);
}

This interface can hide SQL, REST, caching, or in-memory lookup. The abstraction is useful only if priceOf represents a stable domain concept.

Deep versus shallow modules

A “deep” module offers substantial capability behind a small conceptual interface. A shallow wrapper that forwards dozens of vendor-specific operations may add layers without hiding volatility.

Module decomposition test

Ask: If decision X changes, how many modules must know? A useful decomposition concentrates knowledge of X.

Design / research exercise

Choose a volatile technical decision in a system (database, message broker, serialization format, UI framework). Draw the dependency graph before and after introducing a boundary. Identify any leaked types that defeat the boundary.

Suggested reading

  • Parnas on information hiding.
  • Ousterhout, A Philosophy of Software Design (deep modules and complexity).