03 — Cohesion, Coupling & Dependencies¶
Driving question: When do metrics reveal design problems, and when do they merely count structure?
Learning objectives¶
- Explain multiple forms of coupling and cohesion.
- Interpret dependency metrics as proxies rather than ground truth.
- Identify temporal, semantic, and change coupling from repository evidence.
- Relate coupling to testability and change propagation.
Structural and evolutionary coupling¶
Two modules can be weakly coupled in the static dependency graph yet strongly coupled in practice if they nearly always change together. Conversely, a static dependency may be stable and harmless.
Useful evidence includes:
- imports/calls/inheritance;
- shared data schemas;
- co-change frequency;
- issue linkage;
- runtime communication;
- ownership boundaries.
A simple co-change score for files \(a\) and \(b\) can be expressed as:
The metric is not a verdict; it is a clue about hidden dependencies.
Dependency direction¶
Dependency direction should reflect what is stable, policy-rich, or strategically important. A “low-level” persistence implementation depending on a domain interface can preserve domain independence even though calls flow the other way at runtime.
Design / research exercise¶
Mine 100–500 commits from a repository. Find a pair of files/classes with unexpectedly high co-change. Inspect whether the coupling is accidental, semantic, generated, test-related, or architectural.
Suggested reading¶
- Robert C. Martin on coupling and package principles.
- Research literature on logical/evolutionary coupling.