Chapter 3 — Modularity
Why it matters
Introduces the measurable language for talking about how code is organized — the vocabulary you’ll use for the rest of your career to justify structure.
Core ideas
- Modularity is a logical grouping of related code; it’s not the same as physical deployment. It’s an implicit architecture characteristic that almost every system needs.
- Cohesion — how related the parts of a module are. Spectrum from functional (best) down through sequential, communicational, procedural, temporal, logical, to coincidental (worst).
- Coupling — measured via afferent coupling (incoming dependencies, Ca) and efferent coupling (outgoing dependencies, Ce).
- Derived metrics: Abstractness (abstract vs. concrete elements), Instability
I = Ce / (Ce + Ca), and Distance from the main sequence (D) — how balanced a component is between abstractness and instability. The “zone of pain” (too concrete/stable) and “zone of uselessness” (too abstract/unstable). - Connascence (Page-Jones): two components are connascent if changing one requires changing the other. Static connascence (name, type, meaning, position, algorithm) is discoverable by reading code; dynamic connascence (execution order, timing, value, identity) only manifests at runtime. Also strength (static is weaker/easier than dynamic), locality (closer code can tolerate stronger connascence), and degree (how many elements are involved).
Trade-offs to argue
Higher cohesion + looser coupling generally = better maintainability/testability, but you can over-modularize (too many tiny pieces raises orchestration/complexity cost). Connascence guides you to reduce the strength of coupling where code is far apart, and tolerate stronger coupling only where code is local.
Terms to own
cohesion (7 types), afferent/efferent coupling, abstractness, instability, distance from main sequence, connascence (static/dynamic, strength, locality, degree).