Dependência circular.
Interdependência problemática de módulos de software
Na engenharia de software, uma dependência circular (ou dependência cíclica) é uma relação entre dois ou mais módulos que dependem direta ou indiretamente uns dos outros para funcionar corretamente. Tais módulos também são conhecidos como mutuamente recursivos.
Visão geral
Dependências circulares são naturais em muitos modelos de domínio em que certos objetos do mesmo domínio dependem uns dos outros. Entretanto, no design de software, dependências circulares entre módulos de software maiores são consideradas um antipadrão por causa de seus efeitos negativos. Apesar disso, constatou-se que tais dependências circulares (ou cíclicas) são generalizadas entre os arquivos de código-fonte de software do mundo real. Módulos mutuamente recursivos são, contudo, relativamente comuns na programação funcional, onde definições indutivas e recursivas são frequentemente incentivadas.
Problemas
Dependências circulares podem causar muitos efeitos indesejados em programas de software. O mais problemático do ponto de vista do design de software é o acoplamento forte dos módulos mutuamente dependentes, que reduz ou torna impossível a reutilização separada de um único módulo.
Dependências circulares podem causar um efeito dominó quando uma pequena mudança local em um módulo se espalha para outros módulos e tem efeitos globais indesejados (erros de programa, erros de compilação). Dependências circulares também podem resultar em recursões infinitas ou outras falhas inesperadas.
Dependências circulares também podem causar vazamentos de memória ao impedir que certos coletores de lixo automáticos (aqueles que usam contagem de referências) desaloquem objetos não utilizados.
Causas e soluções
Em projetos de software muito grandes, os engenheiros de software podem perder o contexto e inadvertidamente introduzir dependências circulares. Existem ferramentas para analisar software e encontrar dependências circulares indesejadas.
Dependências circulares podem ser introduzidas ao implementar a funcionalidade de callback. Isso pode ser evitado aplicando padrões de projeto como o padrão observador.