Coupling, Cohesion and Demeter
Tell an object what you want instead of walking through its fields, and keep each class about one thing.
Open this lesson in the learning hubKey points
- Cohesion is how much a class is about one thing. Coupling is how much it leans on the shape of others.
- The Law of Demeter: talk to neighbours, not strangers. One dot per call, not
a.getB().getC().getD(). - Every extra dot adds a class you depend on. Change any one of them and this line breaks, although it owns none of them.
- Tell, do not ask: move the behaviour onto the object that holds the data, and call one method that means something.
- Getter chains are the usual sign of low cohesion: the logic ended up outside the class that has the data.
- Builders and streams break the letter of the rule and not the spirit, because each call returns the same kind of thing.
Example
public class Main {
record Money(int cents) {
Money minus(int amount) { return new Money(cents - amount); }
boolean covers(int amount) { return cents >= amount; }
}
static final class Wallet {
private Money money;
Wallet(int cents) { this.money = new Money(cents); }
// TELL, do not ask: the wallet decides, because the wallet owns the money.
boolean pay(int amount) {
if (!money.covers(amount)) return false;
money = money.minus(amount);
return true;
}
int balance() { return money.cents(); }
}
static final class Customer {
private final Wallet wallet;
Customer(int cents) { this.wallet = new Wallet(cents); }
// One forwarding call. Nobody reaches through the customer to the wallet.
boolean pay(int amount) { return wallet.pay(amount); }
int balance() { return wallet.balance(); }
}
public static void main(String[] args) {
Customer customer = new Customer(500);
// The Demeter violation would read like this, and it needs a public
// Wallet, a public Money and a setter before it even compiles:
// customer.getWallet().getMoney().setCents(...)
System.out.println("paid 200? " + customer.pay(200));
System.out.println("paid 500? " + customer.pay(500));
System.out.println("balance " + customer.balance());
}
}
Ask the owner to do the job; a chain of getters is a smell, not a shortcut.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.