Information Hiding
Decompose systems around the decisions most likely to change, and hide each behind an interface.
To an executive
Systems organised around the things most likely to change let us respond to the market without large, risky rewrites. Changes stay small, quick and contained.
To an engineer
List the decisions most likely to change and hide each behind one module or interface. Check that interfaces reveal only what callers need, so internals can change.
The idea
In his 1972 paper in Communications of the ACM, Parnas compared two ways of splitting the same small program into modules. The first followed the processing steps, like a flowchart. The second gave each module a design decision to hide, such as how data was stored. Both worked, but the second was far easier to change, because most changes were confined to a single module.
His conclusion was that you should start from a list of difficult design decisions, or decisions likely to change, and design each module to hide one of them from the rest. This idea underlies encapsulation, APIs and service boundaries. An interface should reveal as little as possible about its internals, so those internals can change freely.
Why it works
Changes follow decisions, not steps. When a data format or vendor changes, every module that knows about it must change. If only one module knows, only one changes.
Narrow interfaces limit coupling. What callers cannot see, they cannot depend on. The less an interface exposes, the more freedom its owner keeps.
It lets people work in parallel. Teams can build and change modules independently once the interfaces between them are stable.
Where it applies
- Service and module boundaries, which should follow volatility rather than workflow steps.
- Integrations with vendors and external formats, which change on someone else's schedule.
- Public APIs and shared libraries, where every exposed detail becomes a contract.
- Data pipelines, which are often split by stage when they should be split by source or format.
How to apply
- List the decisions likely to change: data formats, vendors, algorithms, storage, business rules.
- Give each volatile decision one home, a module or service that owns it entirely.
- Design the interface around what callers need, not around how the module works inside.
- Test the split by walking through likely changes and counting how many modules each one touches.
Example scenario
A reporting system was split into extract, transform and load services. Every new data source or format change touched all three, and releases had to be coordinated across teams.
The team re-split the system by data source, with each service hiding its own format and exposing a common record to the rest. Format changes were now confined to one service, and adding a new source no longer required changes to the others.
Questions to ask
- Which decisions in this design are most likely to change in the next year?
- Does each of those decisions live in exactly one module or service?
- What does this interface reveal that its callers do not need to know?
When not to use it
- Small, stable programs, where the extra interfaces cost more than the changes they would contain.
- Performance-critical paths, where hiding detail can cost efficiency; Parnas himself noted the trade-off and how implementation could address it.
How it misleads you
Hiding so much that consumers cannot do their job and start working around the interface. Hiding also has limits in practice: with enough users, any observable behaviour becomes something someone depends on, so a hidden decision is never quite as free to change as the interface suggests.
Further reading
Last reviewed · Suggest an improvement