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
| Tipo | Categoria | Risco |
|---|---|---|
| Nome | Estática | Baixo |
| Tipo | Estática | Baixo |
| Significado | Estática | Médio |
| Posição | Estática | Médio |
| Algoritmo | Estática | Alto |
| Execução | Dinâmica | Alto |
| Timing | Dinâmica | Muito 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