Зв'язність (coupling) - наскільки модулі залежать один від одного. Чим вона сильніша, тим більше зміна в одному модулі тягне зміни в інших. До неї прагнуть низької.
Зчеплення (cohesion) - наскільки елементи всередині модуля пов'язані спільною метою. До нього прагнуть високого: усе в класі працює на одну задачу.
Девіз: low coupling, high cohesion.
Ознаки сильної зв'язності:
- клас знає внутрішню будову іншого:
$order->customer->address->city->region->name(порушення «закону Деметри»); - спільний змінюваний глобальний стан;
- зміна формату даних в одному модулі ламає кілька інших;
- неможливо протестувати клас, не піднявши половину застосунку;
- модулі імпортують один одного по колу.
Ознаки слабкого зчеплення:
- клас
Utils/Helperз не пов'язаними функціями; - методи класу використовують різні, непересічні набори полів;
- щоб зробити одну зміну, доводиться правити п'ять різних місць - логіку однієї задачі розмазано.
Як зменшують зв'язність:
- залежати від інтерфейсів, а не конкретних класів;
- спілкуватися через події, коли модулю-джерелу не потрібен результат;
- передавати дані (DTO), а не цілі об'єкти з усіма зв'язками;
- приховувати внутрішню будову:
$order->shippingRegion()замість ланцюжка.
Баланс: нульової зв'язності не буває - модулі мусять взаємодіяти. Мета - щоб залежності були явними, спрямованими в один бік (від деталей до бізнес-логіки) і стабільними. Надмірне розщеплення (абстракції й події скрізь) теж має ціну: логіку однієї дії важко простежити.