Why one change should not break ten parts
Coupling and cohesion are two measures of how well a design is split into parts. Low coupling and high cohesion make a system easier to change.
Requirements always change. A good design lets you change one part without breaking the rest. This lesson shows how to count the links that decide that.
By the end of this lesson
Note
I can judge a design by its coupling and cohesion.
Key words
| Word | What it means |
|---|---|
| Module | one part of a system with one job |
| Coupling | how much one part depends on another |
| Cohesion | how well the inside of a part belongs together |
| Interface | the small set of things a part lets others use |
| Fan-out | how many other parts this part uses |
| Fan-in | how many other parts use this part |
The cells students fill in are left blank in this preview.
Coupling is how much parts depend on others
Split a system into modules, parts with one job each. Coupling is how much one module depends on another.
High coupling means a change in one module forces changes in others. Low coupling means a module only knows a small interface: the few things it lets others use.
Count the links in each direction
An arrow means "uses". Fan-out is how many arrows leave a module. Fan-in is how many arrive.
Here orders has fan-out 2 (users and db) and fan-in 1 (web). The db module has fan-out 0 and fan-in 2. A module with a high fan-in is risky to change, because many parts rely on it.
Count links in a file
A design can be kept as a list of lines, one link per line, "from to". The first Run writes the five links to a file and prints nothing.
The next two count lines. Lines starting with orders are its fan-out, so that prints 2. Lines ending with users are its fan-in, so that prints 2.
Write the five links to a file
printf 'web orders\nweb users\norders users\norders db\nusers db\n' > uses.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Count the links leaving orders
grep -c '^orders' uses.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Count the links arriving at users
grep -c 'users$' uses.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think the goal is zero coupling. Modules that never connect cannot make a system. The goal is few, narrow links. Count them, remove the ones that are not needed, and keep the interface small.
Cohesion asks if a part belongs together
Cohesion is how well the inside of one module fits one job. A module that books rooms and also sends invoices and also resizes photos has low cohesion.
High cohesion is easy to name: "bookings". If you need the word "and" to describe a module, split it.
A narrow interface keeps coupling low
The lab's API is a narrow interface. A client asks for one column of one row and knows nothing about how the data is stored. The Run asks for the room of the first booking.
It prints one row with only Lab 2 in it. The database could change its other columns and this client would not notice.
Give psql the password
export PGPASSWORD=shopShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make the bookings table
psql -h db -U shop -c "drop table if exists bookings; create table bookings (id serial primary key, room text not null, slot text not null, booked_by text not null, hours int not null, status text not null default 'booked'); insert into bookings (room, slot, booked_by, hours) values ('Lab 2', 'Mon 10:00', 'Asha', 2), ('Lab 4', 'Mon 10:00', 'Ben', 1), ('Lab 2', 'Tue 14:00', 'Asha', 3); notify pgrst, 'reload schema'"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask for one column of one row
curl -s -w "\n" "http://api:3000/bookings?select=room&order=id&limit=1"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.