ConstructiCat Logo
CodeBust.
Browse section ▾

Циклическая зависимость.

Проблематичная взаимозависимость программных модулей

В программной инженерии циклическая зависимость (или круговая зависимость) — это отношение между двумя или более модулями, которые прямо или косвенно зависят друг от друга для корректной работы. Такие модули также называют взаимно рекурсивными.

Обзор

Циклические зависимости естественны во многих моделях предметной области, где определённые объекты одной предметной области зависят друг от друга. Однако в проектировании ПО циклические зависимости между более крупными программными модулями считаются антипаттерном из-за их негативных эффектов. Несмотря на это, такие циклические (или круговые) зависимости оказались широко распространены среди исходных файлов реального ПО. Взаимно рекурсивные модули, впрочем, довольно обычны в функциональном программировании, где индуктивные и рекурсивные определения часто поощряются.

Проблемы

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

Циклические зависимости могут вызывать эффект домино, когда небольшое локальное изменение в одном модуле распространяется на другие модули и приводит к нежелательным глобальным эффектам (ошибкам программы, ошибкам компиляции). Циклические зависимости также могут приводить к бесконечной рекурсии или иным неожиданным сбоям.

Циклические зависимости могут также вызывать утечки памяти, мешая некоторым автоматическим сборщикам мусора (тем, что используют подсчёт ссылок) освобождать неиспользуемые объекты.

Причины и решения

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

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