Что такое зацепление (coupling) в контексте архитектуры ПО?

«Что такое зацепление (coupling) в контексте архитектуры ПО?» — вопрос из категории Архитектура, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Зацепление (coupling) — это мера взаимозависимости между модулями, классами или компонентами системы. Высокое зацепление означает сильные связи, что делает код хрупким, сложным для понимания, тестирования и изменения. Низкое зацепление — цель хорошего проектирования.

Типы зацепления (от сильного к слабому) с примерами на C++:

  1. Содержательное (Content Coupling): Один модуль напрямую изменяет внутренние данные другого (нарушение инкапсуляции).

    // ПЛОХО: Класс A лезет в приватные поля класса B.
    class B { private: int secret; };
    class A { void hack(B& b) { b.secret = 42; } }; // Нарушение!
  2. Общее (Common Coupling): Модули используют общие глобальные данные.

    // ПЛОХО: Глобальная переменная как канал связи.
    extern int globalState;
    void module1() { globalState = 1; }
    void module2() { if (globalState == 1) { /*...*/ } }
  3. Управляющее (Control Coupling): Один модуль передает другому флаг, управляющий его логикой.

    // НЕИДЕАЛЬНО: Функция делает разную работу в зависимости от флага.
    void processData(Data& data, bool shouldNormalize);
  4. По данным (Data Coupling): Модули обмениваются только необходимыми данными через параметры. Это цель.

    // ХОРОШО: Четкий интерфейс, минимальная зависимость.
    double calculateTax(const Order& order); // Принимает только нужные данные.

Принцип: Стремитесь к слабому зацеплению и сильной связности (high cohesion), когда элементы внутри модуля тесно связаны общей ответственностью.