В чем разница между Cohesion (связность) и Coupling (связанность)?

«В чем разница между Cohesion (связность) и Coupling (связанность)?» — вопрос из категории ООП, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Это фундаментальные концепции проектирования программного обеспечения, описывающие качество структуры кода.

  • Связность (Cohesion) — мера того, насколько тесно связаны обязанности внутри одного модуля (класса, метода). Высокая связность — это хорошо.
  • Связанность (Coupling) — мера того, насколько сильно один модуль зависит от других модулей. Низкая связанность — это хорошо.

Цель: Стремиться к High Cohesion (высокой связности) и Low Coupling (низкой связанности).

Пример на Java:

// Пример НИЗКОЙ связности и ВЫСОКОЙ связанности (плохо)
// Класс делает слишком много: логирует, валидирует, сохраняет в БД и шлет email.
// Он сильно зависит от множества внешних сервисов.
class OrderProcessor {
    private Logger logger;
    private DbService db;
    private EmailService email;
    private Validator validator;

    public void process(Order order) {
        logger.log("Start");
        if (validator.isValid(order)) {
            db.save(order);
            email.sendConfirmation(order);
        }
        logger.log("End");
    }
}

// Пример ВЫСОКОЙ связности и НИЗКОЙ связанности (хорошо)
// Каждый класс имеет одну четкую ответственность.
// OrderService зависит только от абстракций (интерфейсов).
class OrderService {
    private OrderRepository repository; // Интерфейс
    private ConfirmationSender sender; // Интерфейс

    public void placeOrder(Order order) {
        // Высокая связность: метод делает одну вещь — оформляет заказ.
        repository.save(order);
        sender.send(order);
    }
}

interface OrderRepository { void save(Order order); }
interface ConfirmationSender { void send(Order order); }

// Конкретные реализации можно подменить, например, для тестов.
class SqlOrderRepository implements OrderRepository { /* ... */ }
class EmailConfirmationSender implements ConfirmationSender { /* ... */ }

Высокая связность упрощает понимание, тестирование и повторное использование модуля. Низкая связанность уменьшает эффект домино при изменениях: модификация одного модуля минимально затрагивает другие.