exam

Связность и сцепление программных модулей.

Связность и сцепление — ключевые метрики качества модульной архитектуры ПО. Они помогают оценить, насколько удачно система разбита на модули.

Связность (Cohesion)

Связность — мера функциональной целостности и взаимозависимости элементов внутри модуля. Чем выше связность, тем лучше спроектирован модуль.

Уровни связности (от лучшего к худшему):

  1. Функциональная (лучший вариант):
    • все элементы модуля работают вместе для выполнения одной чётко определённой задачи;
    • пример: модуль «Расчёт подоходного налога» выполняет только эту операцию.
  2. Последовательная:
    • выходные данные одной части модуля служат входными для следующей;
    • пример: модуль «Обработка заказа» → проверка наличия → резервирование → формирование счёта.
  3. Информационная (коммуникативная):
    • элементы работают с одними и теми же данными;
    • пример: модуль работы с профилем пользователя (чтение, обновление, удаление).
  4. Процедурная:
    • части связаны последовательностью выполнения, но не общей функцией;
    • пример: «Утренний ритуал» → зарядка → душ → завтрак.
  5. Временная:
    • операции выполняются в один период времени, но не связаны функционально;
    • пример: «Инициализация системы» → загрузить настройки → подключиться к БД → запустить логирование.
  6. Логическая:
    • функции объединены по принципу подобия, но выполняют разные задачи;
    • пример: модуль обработки ошибок (ошибка сети, ошибка БД, ошибка ввода).
  7. Случайная (худший вариант):
    • между элементами нет логической связи;
    • пример: модуль «Разные утилиты» → конвертировать валюту → отправить email → нарисовать график.

Чем выше связность:

  • тем проще тестировать модуль;
  • тем легче его понимать и сопровождать;
  • выше вероятность повторного использования;
  • меньше побочных эффектов при изменениях.

Сцепление (Coupling)

Сцепление — мера взаимозависимости между модулями. Чем слабее сцепление, тем лучше архитектура.

Типы сцепления (от лучшего к худшему):

  1. Сцепление по данным (Data Coupling):
    • модули обмениваются простыми данными (параметрами);
    • каждый параметр — элементарный информационный объект;
    • пример: calculateTax(income, region).
  2. Сцепление по образцу (Stamp Coupling):
    • передаётся структурированный объект (запись, структура);
    • риск избыточности данных;
    • пример: передача объекта UserProfile вместо отдельных полей.
  3. Сцепление по управлению (Control Coupling):
    • один модуль управляет логикой другого через флаги;
    • ухудшает независимость;
    • пример: processOrder(order, isUrgent).
  4. Сцепление по общей области (Common Coupling):
    • модули используют общие глобальные данные;
    • изменения в одном месте влияют на другие модули;
    • пример: глобальная переменная currentUser.
  5. Сцепление по содержимому (Content Coupling):
    • один модуль напрямую обращается к внутренним данным другого;
    • нарушает инкапсуляцию;
    • пример: изменение полей объекта другого модуля напрямую.
  6. Патологическое сцепление (Pathological Coupling):
    • модуль зависит от внутренней реализации другого;
    • любое изменение в одном ломает другой;
    • самый опасный тип.

Чем слабее сцепление:

  • тем легче заменять модули;
  • ниже риск «эффекта домино» при ошибках;
  • проще тестировать модули изолированно;
  • выше гибкость системы.

Взаимосвязь связности и сцепления

Между этими понятиями существует обратная зависимость:

  • Высокая связность внутри модулей → слабое сцепление между ними.
  • Низкая связность (элементы разнородны) → сильное сцепление (модули вынуждены часто взаимодействовать).

Идеальная ситуация:

  • модули с высокой связностью (каждый делает одну чёткую задачу);
  • модули со слабым сцеплением (минимальная зависимость друг от друга).

Практические рекомендации

Для повышения связности:

  • следуйте принципу единственной ответственности (SRP): каждый модуль — одна задача;
  • объединяйте связанные данные и операции в одном модуле;
  • избегайте «сборных» модулей с разнородной функциональностью;
  • регулярно рефакторите код для улучшения связности.

Для ослабления сцепления:

  • используйте интерфейсы и абстракции вместо прямых зависимостей;
  • применяйте внедрение зависимостей (DI);
  • минимизируйте количество и сложность параметров между модулями;
  • отдавайте предпочтение передаче данных вместо управления;
  • избегайте глобальных переменных;
  • используйте событийно‑ориентированный подход для слабой связанности.

Инструменты контроля:

  • статические анализаторы кода (SonarQube, ESLint, Pylint);
  • метрики связности/сцепления в IDE;
  • архитектурные тесты;
  • регулярные код‑ревью.

Пример: сравнение плохого и хорошего проектирования

Плохой вариант (низкое качество):

  • модуль «Утилиты» (случайная связность): конвертирует валюту, отправляет email, рисует графики;
  • модули напрямую обращаются к глобальным переменным (сильное сцепление).

Хороший вариант (высокое качество):

  • модуль «Конвертер валют» (функциональная связность);
  • модуль «Email‑сервис» (функциональная связность);
  • модуль «Графики» (функциональная связность);
  • взаимодействие через интерфейсы и передачу данных (слабое сцепление).

Вывод

Баланс между высокой связностью и слабым сцеплением — основа качественной модульной архитектуры. Это:

  • упрощает разработку и тестирование;
  • снижает стоимость сопровождения;
  • повышает гибкость системы;
  • облегчает масштабирование;
  • уменьшает количество ошибок при внесении изменений.