Concept · Code design

Coupling and cohesion

Keep things that change together in one place (high cohesion) and minimise what each part knows about the others (low coupling).

3 minloose couplinghigh cohesionshotgun surgeryconnascence

Coupling measures how much one module depends on another's details. Cohesion measures how closely the contents of one module belong together. The goal, stated by Larry Constantine in the 1970s and still the best single test of a design, is low coupling and high cohesion: changes stay local, and each module is understandable on its own.

Coupling, from worst to best

KindWhat's sharedExample
ContentOne module edits another's internalsreaching into another package's unexported state via reflection
CommonGlobal mutable statea package-level var currentConfig many modules write
ControlA flag telling another module what to doRender(doc, true)
StampA large structure when only a field is neededpassing a whole User to compute a display name
DataOnly the values neededDisplayName(first, last string)
MessageCalls through a narrow interface or eventspublishing OrderPaid

Coupling can also be temporal (things must happen in a particular order) or hidden in shared databases, file formats and assumptions — a column two services both write is coupling, even with no import between them.

Cohesion

A cohesive module's parts change for the same reason. billing holding invoices, tax rules and payment retries is cohesive. utils holding date formatting, HTTP retries and a slug generator has only coincidental cohesion — the parts are together because someone had to put them somewhere. Low cohesion shows up as divergent change (one file edited for unrelated reasons); high coupling shows up as shotgun surgery (one change touches many files).

Using it

  • Group code by feature, not by technical layer — see package by feature.
  • Depend on small interfaces rather than concrete types (dependency inversion).
  • Pass only the data a function needs.
  • Ask of every change: how many places did I have to touch, and did they belong together?

Zero coupling isn't the goal — modules that never interact do nothing useful. The aim is to make each dependency deliberate, narrow and stable. The design principles lesson builds the other principles on this pair.

Learn it in depth