The Architecture Reference

Fnd components · Foundations · Beginner

Components and Coupling

Components as the architect's primary building block, and the afferent/efferent coupling that measures how they depend on one another.

Fnd components Beginner ⏱ 4 min read Complete

🧱 Analogy

Think of components as the rooms of a house and coupling as the doorways between them. A room everyone walks through (the hallway) is depended on by many — fan-in. A room that opens onto many others is itself dependent on many — fan-out. Too many doorways and the house becomes a maze where moving one wall disturbs the rest.

Components: the physical building block

A component is the physical packaging of modules — a directory or namespace (e.g. app/order/payment → the “Payment Processing” component) that holds the source code for one business function. It is the architect’s primary building block and the lowest level the architect directly designs; class and function design belong to developers. Components come in varieties: libraries (run in the caller’s memory), subsystems/layers, and services (own address space, network communication — the building block of microservices).

Each component must have a single, clear responsibility and a descriptive name — even functionality you outsource to a third-party library is still part of the logical architecture.

Coupling: how components depend on each other

Two components are coupled if a change in one might force a change in the other. Coupling is measured in two directions (Yourdon and Constantine):

graph TD
AR["Auction Registration"] --> BP["Bidder Profile"]
AP["Automatic Payment"] --> BP
BC["Bid Capture"] --> BS["Bid Streamer"]
BC --> BT["Bid Tracker"]
BP -. "CA = 2 (fan-in)" .- BP
BC -. "CE = 2 (fan-out)" .- BC
  • Afferent coupling (CA) — incoming / fan-in: how many components depend on this one. Bidder Profile, depended on by two components, has CA = 2.
  • Efferent coupling (CE) — outgoing / fan-out: how many components this one depends on. Bid Capture, depending on two, has CE = 2.
  • Total coupling (CT) = CA + CE per component; summed across the system, it gives the overall coupling level — telling you the most-coupled component and the system’s overall health.

A mnemonic: a before e = incoming before outgoing; efferent = exit.

The Law of Demeter

The Law of Demeter (Principle of Least Knowledge) is named for the Greek goddess of agriculture, who produced grain but had no knowledge of what mortals did with it. The principle: a component should have limited knowledge of other components. Less knowledge means less coupling.

⚠️ Moving knowledge isn't removing it

If Order Placement knows too much and orchestrates everything (high CT), moving the “low stock” logic into Inventory Management lowers Order Placement’s coupling but raises Inventory Management’s — total system coupling is unchanged because the knowledge was moved, not removed. Only deleting unnecessary knowledge reduces total coupling.

Loose coupling is a trade-off

The First Law applies even here:

  • Tightly coupled (one component orchestrates): you can read the whole workflow in one place, but that component depends on many others and breaks when they change.
  • Loosely coupled (knowledge distributed): components evolve independently, but no single place reveals the full workflow — you must visit many components to understand it.
graph TD
subgraph Tight["Tightly coupled — readable, fragile"]
  O["Order<br/>(orchestrates all)"] --> P1["Payment"]
  O --> I1["Inventory"]
  O --> S1["Shipping"]
end
subgraph Loose["Loosely coupled — independent, diffuse"]
  P2["Payment"] -. "reacts" .-> I2["Inventory"]
  I2 -. "reacts" .-> S2["Shipping"]
end

💡 Key insight

The goal is not zero coupling — complex software requires some. The goal is appropriate coupling: restrict it to the tightest scope possible to avoid brittleness, then govern it with metrics.

See also

When to use it — and when not

✅ Reach for it when

  • When defining the functional building blocks of a system and their responsibilities
  • When you need to reason about which components are most depended-upon or most fragile
  • When deciding where knowledge should live to keep coupling manageable

⛔ Think twice when

  • When tempted to eliminate all coupling — some is necessary, and 'loose' is itself a trade-off
  • When micromanaging class-level design that belongs to developers

Check your understanding

Score: 0 / 4

1. What is a logical component, physically?

A component is the physical packaging of modules, typically represented as a directory/namespace with one clear role.

2. Afferent coupling (CA) of a component measures…

Afferent = incoming/fan-in; efferent = outgoing/fan-out. Mnemonic: a before e = incoming before outgoing; efferent = exit.

3. What does the Law of Demeter (Principle of Least Knowledge) advise?

Less knowledge → less coupling; moving knowledge between components changes where coupling lives, but only removing knowledge reduces total system coupling.

4. Is loose coupling always better?

Tightly coupled orchestration makes a workflow easy to read in one place but fragile; loose coupling is more independent but harder to follow end-to-end.

Comments

Sign in with GitHub to join the discussion.