Card 02/ 09

ConceptDifficulty: Beginner2 min

Coupling and Cohesion

How much a class leans on others, and how much its own parts belong together.

Coupling and cohesion are the two measures that decide how easily a design changes. Coupling is how much one class depends on the details of other classes. Cohesion is how closely the parts inside one class belong together. Every SOLID principle moves a design the same way: coupling down and cohesion up. This card defines both and shows what each looks like in a class.

A dependency is any other piece of code a class needs in order to work: a class it creates, a method it calls, a field it reads. High coupling means a class has many dependencies, or depends on details of them that could change, such as a particular database driver. When one of those details changes, the coupled class has to change too. That is where rigidity and fragility come from.

High cohesion means every method and field in a class serves the same purpose. A class with low cohesion mixes jobs that change for different reasons, such as pricing and sending email. When either job changes, the whole class is opened, and the other job is put at risk.

The same order code, tangled and cohesive

TangledHigh coupling, low cohesion

One Order class that:

  • calculates prices and discounts
  • creates its own MySQL connection
  • creates its own SMTP mail client
  • formats the receipt text

It depends on two concrete libraries, and four unrelated jobs live in one place.

CohesiveLow coupling, high cohesion

Three small classes:

  • Pricing calculates prices and discounts
  • OrderStore saves orders through a store it is given
  • ReceiptSender formats and sends the receipt through a sender it is given

Each has one job, and none creates the database or mail client it uses.

A kitchen makes the two measures concrete. A cohesive drawer holds the cutlery together, so you know where a fork lives. A coupled recipe needs a tool from every drawer in the room, so rearranging any drawer breaks the recipe. The analogy has a limit: a drawer cannot change what the drawer next to it does, while a coupled class can, because a change inside one class can alter the behaviour of every class that calls it.

The two measures pull together. Splitting a class by purpose raises cohesion, and once each part has fewer jobs it usually needs fewer dependencies, which lowers coupling.