Skip to content

Tensions in Practice: Information hiding in tension with runtime observability

Software modules · change and diagnosis

A software module is easier to change when callers depend on a stable interface rather than its internal workings. But someone diagnosing a failure may need evidence from inside. Hiding everything can obstruct diagnosis; exposing everything can let callers depend on details that should remain changeable. Compare those extremes with a separate diagnostic interface, which gives ordinary use and investigation different contracts.

Preserve freedom to change

Keep ordinary callers dependent on a stable functional contract, not on changeable implementation details.

Make failures diagnosable

Give investigators enough evidence of internal behavior to understand failures and performance problems.

Why these aims pull against each other

The aims interfere when one exposure boundary serves both ordinary use and diagnosis. Closing it can hide needed evidence; opening it can expose implementation details that callers start relying on.

Compare the arrangements

Hide internals

Ordinary callers use the functional interface. The diagnostic observer has no separate view of internal state.

What it protects
Callers are shielded from implementation details they should not depend on.
What it costs
A failure can remain a black box even to the module’s developers.
When it fits
This represents over-hiding: it fits only as a contrast where the available functional outputs do not supply the evidence needed for investigation.

Illustration note: The sealed observer path is an editorial sketch of the source’s over-hiding failure mode. Information hiding itself does not require diagnostic blindness.

Expose internals

Both callers and the diagnostic observer can inspect internal implementation details.

What it protects
Internal evidence becomes available for debugging and performance investigation.
What it costs
Callers can start depending on the exposed details, so an internal change may require caller changes too.
When it fits
The coupling risk arises when callers rely on implementation details; exposure alone does not prove that every caller becomes coupled.

Illustration note: This is an editorial sketch of the source’s under-hiding failure mode. The source supports the risk of dependency; the specific actors and access paths are illustrative.

Separate interfaces

Keep ordinary use behind the functional interface and expose diagnostic state through a defined debug or monitoring interface.

What it protects
Investigation gains an explicit evidence path without making raw implementation details part of the ordinary functional contract.
What it costs
The diagnostic contract also needs design and maintenance. Separate interfaces do not remove hidden timing, shared-resource or other runtime coupling.
When it fits
Callers must continue to use the functional contract, and the diagnostic outputs must support the failures being investigated.

Illustration note: Separate debug or monitoring interfaces are the source-backed response. The extra contract-maintenance cost is an editorial inference from the source’s broader account of interface-design overhead; it is not a measured cost.

What this illustration does—and does not—establish

Modularity: Information hiding versus runtime observability supplies the conflict and the separate-interface response. The three arrangements make its two failure modes and response visible; their actors, paths and some applicability conditions are editorial interpretations. No arrangement is presented as universally best.

  • Separate diagnostic interfaces do not establish complete observability or eliminate every dependency between modules.
  • Generic roles such as caller, module and diagnostic observer are illustrative actors, not additional catalog entities.
  • This case concerns freedom from implementation dependencies. A diagnostic interface can still expose protected user information.

Source entries

Modularity

Prime · Source of the tension

Information hiding versus runtime observability supplies the conflict, both failure extremes, and the response of separating diagnostic and functional interfaces.

Information hiding versus runtime observability

- T4: Information hiding versus runtime observability. Modular design emphasizes hiding internal state and implementation details; however, effective debugging and performance analysis require visibility into what is happening inside modules. Debuggers, profilers, and logging systems need access to internal state that a strictly hidden module does not expose. The tension is between the design principle of hiding information (allowing independent modification) and the operational need for visibility (understanding failures and bottlenecks). A mature approach exposes internal state through well-defined debug or monitoring interfaces, separate from the functional interface. A common failure is either over-hiding (modules are black boxes even to their developers when something goes wrong) or under-hiding (exposing so much internal state that modules are implicitly dependent on internal details)*.

Read the source section

What It Is Not

- Not costless. Achieving modularity requires disciplined interface design, documentation, and often adds abstraction layers and indirection that introduce computational or cognitive overhead. A tightly coupled monolith may be faster or simpler to implement in the short term. Modularity is an investment whose returns are primarily in long-term maintainability, not short-term construction speed.

Read the source section

What It Is Not

- Not a guarantee of independent runtime behavior. Two modules with clearly-specified interfaces and no direct code dependencies can still produce coupled *system* behavior through hidden runtime conditions — timing assumptions (one service expects another to respond within a particular latency), resource contention (shared CPU, memory, or network bandwidth), data consistency expectations (one module assumes a state another module is responsible for maintaining), or operational context (deployment topology, configuration drift). Newman's 2015 microservices analysis catalogs these failure modes systematically: low coupling at the *interface* level does not entail loose coupling at the *system* level.

Read the source section

Information Hiding

Prime · Related concept

Defines the protected aim as controlling dependencies through a stable public surface, rather than secrecy for its own sake.

Core Idea

Information hiding is the structural pattern of *deliberately concealing some internal facts about a system behind a stable public surface, so that consumers of the system interact only with the surface and remain unable — and unconcerned — about what lies behind*. The motivating commitment is that *what consumers do not need to know, they should not be in a position to depend on*, and the mechanism is a controlled boundary that filters which facts cross.

Read the source section

Observability

Prime · Related concept

Clarifies that diagnosis depends on inferring state from outputs; a general promise of openness is not enough.

What It Is Not

- Not visibility or transparency broadly — observability is the structural ability to infer state from outputs, not a general openness or trust property. A closed-source system can be highly observable to its operators (extensive telemetry) or barely observable; visibility to external parties is a separate concern.

Read the source section