Skip to main content

Conascência (Connascence) em Arquitetura de Software | Livro - Fundamentos de Arquitetura de Software

  • Conascência (Connascence) em Arquitetura de Software | Livro - Fundamentos de Arquitetura de Software

Referência

O conceito de conascência é apresentado no livro Fundamentos de Arquitetura de Software, de Mark Richards e Neal Ford.

Conascência é um modelo formal para analisar acoplamento estrutural e comportamental entre partes de um sistema.


Definição Formal

Conascência ocorre quando:

Uma mudança em um elemento do sistema exige mudança correspondente em outro elemento para preservar a correção.

Ela responde à pergunta arquitetural:

O que dois componentes precisam saber um do outro para funcionarem corretamente?

Diferente da noção genérica de "acoplamento", a conascência classifica qual tipo de conhecimento compartilhado existe.


Dimensões da Conascência

A severidade da conascência aumenta conforme:

1. Grau (Degree)

Quantos elementos estão envolvidos.

2. Distância (Distance)

Quão separados estão os elementos:

  • Mesma classe → impacto baixo
  • Módulos diferentes → impacto médio
  • Serviços diferentes → impacto alto

3. Frequência de Mudança (Volatility)

Quanto mais frequentemente um dos lados muda, maior o risco.


Classificação dos Tipos de Conascência

A literatura divide em:

  • Conascência Estática (tempo de compilação)
  • Conascência Dinâmica (tempo de execução)

Conascência Estática

Ocorre quando a dependência é verificável em compile-time.

Conascência de Nome (CoN)

Duas partes dependem do mesmo identificador.

public void CalcularImposto() { }

servico.CalcularImposto();

Renomear o método exige alterar todos os consumidores.

Impacto: Baixo Gerenciamento: IDE + refatoração automática


Conascência de Tipo (CoT)

Uma parte depende do tipo exato retornado.

public decimal ObterTotal()

Alterar para double impacta todos os consumidores.

Impacto: Baixo a médio


Conascência de Significado (CoM)

Compartilhamento implícito de significado sem estrutura formal.

if (pedido.Status == 1)
{
// 1 significa "Aprovado"
}

Mudança no significado exige sincronização manual.

Impacto: Médio

Melhor abordagem:

public enum StatusPedido
{
Aprovado,
Rejeitado
}

Conascência de Posição (CoP)

Dependência da ordem dos parâmetros.

ProcessarPedido(clienteId, valor, true);

Se a ordem mudar, o comportamento pode se corromper silenciosamente.

Mitigação:

ProcessarPedido(new PedidoOptions
{
ClienteId = clienteId,
Valor = valor,
AplicarDesconto = true
});

Impacto: Médio


Conascência de Algoritmo (CoA)

Dois módulos precisam conhecer a mesma lógica interna.

Exemplo:

// Cliente
var hash = GerarHash(senha);

// Servidor
if (GerarHash(inputSenha) == hashArmazenado)

Se o algoritmo mudar, ambos devem ser alterados simultaneamente.

Impacto: Alto


Conascência Dinâmica

Ocorre quando a dependência só pode ser observada em tempo de execução.

Mais crítica em arquiteturas distribuídas.


Conascência de Execução (CoE)

A ordem de execução importa.

InicializarBanco();
CarregarCache();

Se a ordem for invertida, falha.

Impacto: Alto


Conascência de Timing (CoTg)

Uma parte depende do momento exato em que outra executa.

Exemplo clássico:

  • Serviço A envia evento
  • Serviço B precisa estar ativo naquele exato instante

Impacto: Muito alto Especialmente perigoso em microsserviços e sistemas orientados a eventos.


Regra Arquitetural Fundamental

A diretriz proposta no livro é:

Minimizar conascência global Permitir conascência local

Ou seja:

  • Dentro de um módulo → conascência é aceitável
  • Entre módulos → deve ser reduzida
  • Entre serviços → deve ser mínima

Isso se relaciona diretamente com:

  • Modularidade
  • Independência de deploy
  • Evolução independente de serviços
  • Escalabilidade organizacional

Conascência vs Acoplamento Tradicional

Acoplamento tradicional diz:

"Esses módulos estão fortemente acoplados."

Conascência diz:

"Eles possuem conascência de algoritmo e de timing."

Essa especificidade permite decisões arquiteturais mais precisas.


Aplicação em Arquiteturas Modernas

Microsserviços

Evitar:

  • Conascência de banco compartilhado
  • Conascência de schema rígido
  • Conascência temporal síncrona

Preferir:

  • Eventos assíncronos
  • Versionamento de contratos
  • Comunicação tolerante a falhas

Domain-Driven Design

Conascência deve ser:

  • Alta dentro do Aggregate
  • Baixa entre Bounded Contexts

Isso preserva autonomia de domínio.


Heurística Prática para Revisão de Código

Perguntas diagnósticas:

  • Se eu alterar este método, quantos arquivos preciso modificar?
  • Existe conhecimento implícito não formalizado?
  • A ordem de execução é crítica?
  • Dois serviços precisam mudar juntos?

Se a resposta for "sim" com frequência elevada, existe conascência problemática.


Síntese Estrutural

TipoCategoriaRisco
NomeEstáticaBaixo
TipoEstáticaBaixo
SignificadoEstáticaMédio
PosiçãoEstáticaMédio
AlgoritmoEstáticaAlto
ExecuçãoDinâmicaAlto
TimingDinâmicaMuito Alto

Relação com Evolução do Sistema

Conascência alta implica:

  • Maior custo de mudança
  • Maior risco de regressão
  • Menor independência arquitetural
  • Maior complexidade cognitiva

Conascência controlada implica:

  • Sistemas evolutivos
  • Times independentes
  • Deploy desacoplado
  • Maior estabilidade estrutural