Revisão de arquitetura e fitness functions

1. Fundamentos da Revisão de Arquitetura

A revisão de arquitetura é um processo estruturado de avaliação das decisões arquiteturais de um sistema, com o objetivo de garantir alinhamento técnico, detectar riscos precocemente e promover governança evolutiva. Diferentemente da revisão de código, que foca em implementação, legibilidade e padrões locais, a revisão de arquitetura opera em um escopo mais amplo: analisa estruturas de componentes, fluxos de dados, padrões de comunicação e atributos de qualidade como desempenho, segurança e manutenibilidade.

Enquanto a revisão de código é realizada entre pares desenvolvedores, a revisão de arquitetura envolve múltiplos papéis: o arquiteto de software, líder técnico, equipe de desenvolvimento e, em contextos críticos, revisores externos. A granularidade também difere — a revisão de código examina linhas e funções; a revisão de arquitetura examina módulos, serviços e suas interações.

2. Conceito de Fitness Functions em Arquitetura

O termo fitness function foi popularizado por Neal Ford, Rebecca Parsons e Patrick Kua no livro Building Evolutionary Architectures. Uma fitness function é um teste ou verificação automatizada que avalia se um atributo arquitetural está sendo respeitado. Em essência, são mecanismos objetivos para medir a "aptidão" da arquitetura em relação a requisitos não funcionais.

Existem três tipos principais:

  • Funções de cobertura (pass/fail): retornam sucesso ou falha, como verificar se não há dependências cíclicas.
  • Funções de medição (métricas contínuas): coletam valores ao longo do tempo, como latência média de uma API.
  • Funções de conformidade: validam regras específicas, como uso obrigatório de criptografia em dados sensíveis.

A grande inovação das fitness functions é permitir que decisões arquiteturais sejam validadas continuamente, em vez de apenas em revisões periódicas.

3. Integração das Fitness Functions no Ciclo de Revisão

O pipeline de CI/CD é o ambiente natural para execução de fitness functions. Elas podem ser acionadas por diferentes gatilhos: commits, pull requests, releases ou agendamento temporal (ex.: diariamente). Isso transforma a revisão de arquitetura de um evento pontual em um processo contínuo.

Abaixo, um exemplo de fitness function para detectar acoplamento cíclico entre módulos, utilizando uma abordagem simplificada:

# Exemplo: Fitness function para acoplamento cíclico (pseudocódigo)
função verificar_acoplamento_ciclico():
    grafo_dependencias = extrair_dependencias_entre_modulos()
    ciclos = encontrar_ciclos(grafo_dependencias)

    se tamanho(ciclos) > 0:
        registrar_falha("Acoplamento cíclico detectado entre: " + ciclos)
        retornar FALHA
    senão:
        registrar_sucesso("Nenhum ciclo encontrado")
        retornar SUCESSO

Essa função pode ser executada em um pipeline como:

# .github/workflows/arch-review.yml (exemplo conceitual)
passos:
  - nome: Verificar acoplamento cíclico
    executar: python fitness_functions/cyclic_dependency.py

4. Categorias Práticas de Fitness Functions

Acoplamento e coesão

Verificam dependências circulares, limites de fan-in/fan-out e violações de camadas.

# Exemplo: verificar se módulo X depende de módulo Y (proibido)
função verificar_dependencia_proibida(modulo_x, modulo_y):
    dependencias = listar_dependencias_diretas(modulo_x)
    se modulo_y em dependencias:
        registrar_falha("Módulo " + modulo_x + " não deve depender de " + modulo_y)
        retornar FALHA
    retornar SUCESSO

Performance e latência

Estabelecem thresholds máximos para tempo de resposta em endpoints críticos.

# Exemplo: threshold de latência para API de pagamentos
função verificar_latencia_pagamentos():
    latencia_media = medir_tempo_resposta("/api/pagamentos", 100 requisicoes)
    limite_maximo = 200  # milissegundos
    se latencia_media > limite_maximo:
        registrar_alerta("Latência média excedida: " + latencia_media + "ms")
        retornar FALHA
    retornar SUCESSO

Resiliência e tolerância a falhas

Verificam a presença de circuit breakers, políticas de retentativa e timeouts configurados.

Segurança e conformidade

Validam regras de criptografia, versões de bibliotecas conhecidas por vulnerabilidades e headers HTTP obrigatórios.

5. Estruturando a Revisão Tradicional com Suporte das Fitness Functions

A automação não substitui a revisão humana — complementa. Um checklist de revisão manual deve cobrir aspectos que fitness functions não alcançam: decisões de design, trade-offs entre atributos de qualidade e adequação ao domínio do negócio.

Uma sessão típica de revisão pode seguir este fluxo:

  1. Análise do diagrama C4 (contexto, containers, componentes, código).
  2. Execução automatizada das fitness functions no pipeline.
  3. Discussão dos resultados: falhas indicam problemas objetivos; alertas sugerem atenção.
  4. Documentação em ADRs (Architecture Decision Records): atualizar ADRs com base em falhas ou alertas.
# Exemplo: ADR atualizado após falha em fitness function
# ADR-023: Decisão de modularização do serviço de notificações
# Motivo: Fitness function detectou acoplamento cíclico entre módulo de email e SMS
# Decisão: Extrair interface comum e inverter dependência via injeção

6. Métricas e Governança ao Longo do Tempo

Para que a governança seja efetiva, é essencial acompanhar a evolução das fitness functions em um dashboard. Métricas como histórico de aprovações, taxa de falhas por categoria e tendências de degradação permitem decisões informadas.

Limites de tolerância podem ser graduais:

  • Soft fail: alerta registrado, mas pipeline não é bloqueado.
  • Hard fail: pipeline é interrompido se o limite for excedido.

A relação com métricas de modularidade é direta: ao medir acoplamento e coesão ao longo do tempo, é possível identificar melhoria ou degradação arquitetural. Por exemplo, um aumento gradual no fan-out médio de um módulo pode indicar erosão da arquitetura.

7. Armadilhas e Boas Práticas

Armadilhas comuns:

  • Fitness functions frágeis: muito específicas ou dependentes de detalhes de implementação que mudam com frequência. Isso gera manutenção excessiva e falsos positivos.
  • Automação excessiva: tentar cobrir tudo com código ignora que decisões arquiteturais envolvem contexto de negócio, trade-offs e visão estratégica.
  • Falta de evolução: as funções precisam ser revisadas periodicamente para refletir mudanças nos requisitos arquiteturais.

Boas práticas:

  • Adoção incremental: comece com funções críticas (ex.: dependências cíclicas, latência de endpoints principais) e expanda gradualmente.
  • Equilíbrio homem-máquina: use fitness functions para verificar o que é mensurável objetivamente; reserve a revisão humana para análise de design, riscos emergentes e alinhamento estratégico.
  • Documentação e rastreabilidade: associe cada fitness function a um atributo arquitetural e a um ADR correspondente.

A revisão de arquitetura apoiada por fitness functions transforma a governança de um evento esporádico em um processo contínuo, mensurável e evolutivo. Quando bem implementada, ela permite que equipes entreguem valor com confiança, sabendo que a arquitetura permanece saudável mesmo diante de mudanças constantes.


Referências