Coupling is the degree to which one module depends on another — how many connections cross the boundary, how wide they are, and how much each side must know about the other’s internals. High coupling makes change contagious: touch one module and its dependents break.
Reducing coupling is not eliminating dependencies — a system with none does nothing. It makes the remaining dependencies fewer, narrower, and explicit, so change stays local.
How It Works
- Encapsulate — put an explicit interface in front of a module; dependents bind to the interface, leaving the internals free to change.
- Use an intermediary — place a broker, mediator, or message bus between two modules so neither names the other directly.
- Restrict dependencies — limit which modules a module may reference, through visibility rules or a layered, acyclic dependency policy.
- Abstract common services — hide several similar dependencies behind one shared contract, so a dependent binds once instead of per provider.
Failure Modes
- Speculative interfaces wrap code that has one implementation and always will — indirection that decouples nothing.
- The intermediary becomes a hub every path crosses, turning into a new coupling point and a bottleneck.
- Dependency rules so strict that teams route around them with skip-layer calls or duplicated logic.
Verification
- Coupling metrics stay inside a threshold: efferent and afferent coupling (Ce/Ca), instability, CBO per class.
- An architecture-conformance test fails the build on any disallowed or cyclic module dependency.
- Change-coupling analysis: files that keep changing together despite no static link expose residual coupling.
Variants and Related Tactics
- Increase Cohesion is the complementary lever — see that page.
- Defer Binding reduces coupling across time: postponing a choice to configuration or runtime removes a caller’s compile-time dependence on a specific implementation.
- Connascence grades coupling by strength and locality, a finer vocabulary than “loose versus tight”.
- Hexagonal, Layered, and Publish-Subscribe are pattern-scale realisations.
References
- Software Architecture in Practice, 4th ed. — Bass, Clements & Kazman (full citation)
- Balancing Coupling in Software Design — Vlad Khononov (Addison-Wesley, 2024)
- On the Criteria To Be Used in Decomposing Systems into Modules — David Parnas (CACM 15(12), 1972)