Skip to content

Latest commit

 

History

History
268 lines (151 loc) · 43.4 KB

File metadata and controls

268 lines (151 loc) · 43.4 KB

A identificação de módulos coesos e fracamente acoplados é a pedra angular da transição bem-sucedida de um sistema monolítico para uma arquitetura de monólito modular. Em vez de apresentar um conjunto de técnicas isoladas, propomos aqui uma metodologia procedural integrada, onde cada etapa se baseia na anterior, refinando progressivamente a identificação dos limites modulares. Esta abordagem combina múltiplas perspectivas (negócio, código estático, comportamento dinâmico, evolução histórica e feedback humano) para aumentar a confiabilidade dos resultados, sempre correlacionando as escolhas metodológicas com o impacto esperado nas métricas de qualidade.

Visão Geral da Metodologia Procedural:

Diagrama Procedural das etapas Diagrama Procedural das etapas

4.1 Etapa 1: Análise de Domínio e Contextos Delimitados (DDD)

Objetivo Principal: Identificar os limites lógicos fundamentais do negócio refletidos no sistema, visando maximizar a coesão conceitual (CHD - Conceptual Cohesion of Domain) e estabelecer uma base semântica sólida para os módulos.

4.1.1 Input:

  1. Documentação de requisitos funcionais e não funcionais do Evently.
  2. Entrevistas ou workshops com especialistas de domínio (se possível) e stakeholders.
  3. Código-fonte existente (para análise exploratória inicial do domínio).
  4. Modelos de dados existentes.

4.1.2 Processo:

  1. Mapeamento de Linguagem Ubíqua: Identificar os termos e conceitos chave usados pelos especialistas de domínio para descrever as diferentes partes do Evently (ex: Evento, Inscrição, Participante, Pagamento, Notificação, Usuário, Permissão).

  2. Identificação de Subdomínios: Agrupar funcionalidades relacionadas em subdomínios principais (Core Domain, Supporting Subdomains, Generic Subdomains). Por exemplo, no Evently, 'Gerenciamento de Eventos' e 'Processamento de Inscrições' podem ser Core, 'Autenticação/Autorização' pode ser Supporting/Generic, 'Notificações' pode ser Supporting.

  3. Event Storming (Simplificado ou Completo): Mapear os eventos de negócio significativos (ex: EventoCriado, InscricaoRealizada, PagamentoConfirmado, NotificacaoEnviada) e identificar os comandos que os disparam e as políticas/regras associadas. Agrupar eventos e comandos relacionados pode revelar limites naturais.

  4. Mapeamento de Contexto: Definir explicitamente os limites entre os subdomínios identificados, criando Contextos Delimitados (Bounded Contexts) candidatos. Cada contexto deve ter sua própria linguagem ubíqua e modelo conceitual. Por exemplo, o conceito de 'Usuário' pode ter atributos diferentes no contexto de 'Autenticação' vs. 'Inscrição'.

  5. Documentação Inicial dos Contextos: Descrever brevemente a responsabilidade principal de cada Bounded Context candidato (ex: Contexto 'Gestão de Eventos' - responsável por criar, publicar, atualizar e consultar informações sobre eventos; Contexto 'Inscrições' - responsável por registrar participantes em eventos, gerenciar vagas; Contexto 'Pagamentos' - responsável por processar pagamentos de inscrições).

4.1.3 Output:

  1. Lista documentada de Bounded Contexts candidatos a módulos.
  2. Glossário de Linguagem Ubíqua por contexto.
  3. Mapa de Contexto inicial (visual ou textual) mostrando as relações entre os contextos.

4.1.4 Conexão com a Próxima Etapa e Métricas:

A lista de Bounded Contexts serve como input fundamental para a Análise de Dependências Estáticas. A forte coesão conceitual buscada nesta etapa visa diretamente maximizar métricas como CHD e estabelecer uma base para minimizar o acoplamento funcional e semântico entre os futuros módulos.

4.2 Etapa 2: Análise de Dependências Estáticas

  1. Objetivo Principal: Refinar os limites dos módulos candidatos identificados na Etapa 1, analisando as relações estruturais no código-fonte. O foco é agrupar classes/componentes fortemente acoplados internamente e identificar pontos de acoplamento externo que precisam ser gerenciados ou minimizados. Visa-se aumentar a coesão estrutural (ex: LCOM4, SMQ) e reduzir o acoplamento estrutural (ex: CBO, Afferent/Efferent Coupling).

4.2.1 Input:

  1. Código-fonte completo do projeto Evently (.NET 8 / C# 12).
  2. Lista de Bounded Contexts candidatos da Etapa 1.
  3. Ferramentas de análise estática (ex: NDepend, Visual Studio Code Analysis / Roslyn Analyzers, scripts customizados).

4.2.2 Processo:

  1. Construção do Grafo de Dependências: Utilizar ferramentas para mapear as dependências entre classes, namespaces e projetos dentro da solução Evently. Visualizar este grafo pode revelar clusters naturais de componentes interconectados.

  2. Análise de Acoplamento: Calcular métricas de acoplamento para classes e potenciais módulos: CBO (Coupling Between Objects): Contar o número de outras classes/tipos aos quais uma classe está acoplada (usa ou é usada por). Valores altos podem indicar que a classe está muito dispersa ou que o limite do módulo candidato está mal definido.

  • Acoplamento Aferente (Ca): Número de classes externas que dependem de classes dentro do módulo candidato. Alto Ca pode indicar um módulo central/fundamental, mas também um potencial gargalo.
  • Acoplamento Eferente (Ce): Número de classes externas das quais as classes dentro do módulo candidato dependem. Alto Ce indica alta dependência externa, o que prejudica a autonomia do módulo.
  • Instabilidade (I = Ce / (Ca + Ce)): Métrica derivada que varia de 0 (máxima estabilidade) a 1 (máxima instabilidade). Módulos devem ter um equilíbrio apropriado (Princípio da Dependência Estável).
  1. Análise de Coesão Estrutural: Calcular métricas de coesão:
  • LCOM4 (Lack of Cohesion in Methods): Mede quantos "componentes conectados" existem dentro de uma classe com base no compartilhamento de variáveis de instância pelos métodos. Um valor > 1 indica que a classe pode ter mais de uma responsabilidade e talvez deva ser dividida. Ferramentas como NDepend calculam variações desta métrica.
  • SMQ (Structural Modularity Quality - se ferramenta disponível): Métricas mais avançadas que consideram a estrutura interna do módulo como um todo.
  1. Identificação de Ciclos de Dependência: Detectar ciclos de dependência entre namespaces ou projetos, pois eles forçam o acoplamento e dificultam a separação em módulos independentes. Devem ser quebrados através de inversão de dependência ou refatoração.

  2. Refinamento dos Limites: Com base nas métricas e na visualização do grafo, ajustar os limites dos Bounded Contexts candidatos. Classes com alto acoplamento mútuo devem idealmente pertencer ao mesmo módulo. Dependências fortes entre módulos candidatos podem indicar a necessidade de redefinir limites ou introduzir interfaces explícitas.

4.2.3 Output:

  1. Grafo de dependências refinado.
  2. Relatório de métricas de acoplamento e coesão por classe/módulo candidato.
  3. Lista de ciclos de dependência identificados e sugestões para quebrá-los.
  4. Versão revisada da lista de módulos candidatos e seus componentes internos.

4.2.4 Conexão com a Próxima Etapa e Métricas:

Os limites refinados estruturalmente e as métricas calculadas servem de input para a Análise Dinâmica. A análise estática foca em melhorar LCOM4, CBO, Ca/Ce e identificar violações estruturais, complementando a visão de negócio da Etapa 1.

4.3 Etapa 3: Análise Dinâmica (Comportamental)

  1. Objetivo Principal: Validar e refinar os limites modulares observando o comportamento real do sistema em execução, focando nos padrões de comunicação e fluxos de dados entre componentes. Busca identificar acoplamentos não óbvios estaticamente e avaliar a intensidade das interações, visando minimizar o acoplamento em tempo de execução e validar a coesão funcional.

4.3.1 Input:

  1. Aplicação Evently instrumentada ou com logging/tracing detalhado habilitado.
  2. Conjunto de cenários de uso representativos (casos de teste, simulação de carga).
  3. Ferramentas de profiling, tracing distribuído (se aplicável, ex: OpenTelemetry com Jaeger/Zipkin) ou análise de logs (ex: Seq, ELK stack).
  4. Lista de módulos candidatos refinada na Etapa 2.

4.3.2 Processo:

  1. Execução de Cenários: Rodar a aplicação Evently sob os cenários de uso definidos, coletando dados de execução (chamadas de método, queries a banco, mensagens trocadas, tempos de resposta).

  2. Análise de Fluxos de Transação: Mapear as sequências de interações entre os componentes (identificados como pertencentes aos módulos candidatos) para realizar operações de negócio chave (ex: fluxo de inscrição completa, desde a UI até a confirmação do pagamento e notificação).

  3. Identificação de Acoplamento Oculto: Procurar por interações intensas ou inesperadas entre componentes que pertencem a módulos candidatos diferentes. Isso pode incluir:

  • Chatty communication: Muitas chamadas de baixo nível entre módulos para completar uma única operação.

  • Dependências de dados compartilhados: Acesso frequente e concorrente à mesma tabela de banco de dados por múltiplos módulos candidatos (pode indicar um limite mal definido ou a necessidade de uma API de dados).

  • Transações distribuídas implícitas: Operações que requerem coordenação complexa ou rollbacks entre múltiplos módulos.

  1. Análise de Frequência e Latência: Quantificar a frequência das chamadas entre módulos candidatos e a latência associada. Interações muito frequentes ou de alta latência podem indicar um ponto de acoplamento problemático.

  2. Refinamento com Base no Comportamento: Ajustar os limites modulares com base nos padrões de comunicação observados. Componentes que colaboram muito intensamente em tempo de execução talvez devam pertencer ao mesmo módulo, mesmo que a análise estática sugerisse separação.

4.3.3 Output:

  1. Mapas de interação ou sequência para fluxos de negócio chave.
  2. Lista de pontos de acoplamento em tempo de execução identificados (chatty communication, dados compartilhados, etc.).
  3. Dados quantitativos sobre frequência e latência de interações entre módulos candidatos.
  4. Versão novamente revisada da lista de módulos candidatos.

4.3.4 Conexão com a Próxima Etapa e Métricas:

Os insights sobre o comportamento real complementam a visão estática e servem de input para a Análise de Evolução. A análise dinâmica ajuda a validar a coesão funcional (componentes que trabalham juntos em runtime) e a identificar acoplamentos de desempenho ou comportamentais que métricas estáticas não capturam.

4.4 Etapa 4: Análise da Evolução do Código (Histórico de Versões)

  1. Objetivo Principal: Identificar módulos ou componentes que tendem a mudar juntos ao longo do tempo, sugerindo um acoplamento lógico ou funcional (coesão de mudança). Esta análise ajuda a descobrir dependências que não são óbvias nas análises estática ou dinâmica.

4.4.1 Input:

  1. Histórico completo do repositório Git do projeto Evently.
  2. Ferramentas de análise de histórico de versões (ex: scripts customizados usando git log, ferramentas como CodeScene ou similares que analisem co-mudança).
  3. Lista de módulos candidatos refinada na Etapa 3.

4.4.2 Processo:

  1. Análise de Co-mudança (Co-change): Analisar o histórico de commits para identificar arquivos ou classes que são frequentemente modificados juntos no mesmo commit. Pares ou grupos de arquivos com alta frequência de co-mudança são fortes candidatos a pertencerem ao mesmo módulo lógico.

  2. Análise de Acoplamento Temporal: Investigar sequências de commits onde mudanças em um componente são frequentemente seguidas por mudanças em outro em commits subsequentes. Isso pode indicar uma dependência lógica ou um fluxo de trabalho comum.

  3. Identificação de Hotspots de Mudança: Localizar arquivos ou componentes que sofrem modificações muito frequentes. Hotspots podem indicar áreas complexas ou instáveis, mas se um hotspot interage frequentemente com outros componentes específicos, isso pode informar os limites modulares.

  4. Mapeamento com Módulos Candidatos: Cruzar os resultados da análise de co-mudança com a estrutura dos módulos candidatos. Se arquivos que mudam juntos estão espalhados por diferentes módulos candidatos, isso sugere que os limites podem precisar de ajuste para agrupar esses componentes logicamente acoplados.

4.4.3 Output:

  1. Lista de grupos de arquivos/classes com alta frequência de co-mudança.

  2. Identificação de padrões de acoplamento temporal.

  3. Mapa de hotspots de mudança.

  4. Sugestões de refinamento dos limites modulares com base na coesão de mudança.

4.4.4 Conexão com a Próxima Etapa e Métricas:

Os insights sobre acoplamento lógico complementam as visões de negócio, estática e dinâmica, fornecendo mais uma evidência para o refinamento final dos limites. A coesão de mudança é uma métrica qualitativa/quantitativa importante que direciona esta etapa.

4.5. Etapa 5: Integração das Análises, Validação Humana e Refinamento Iterativo

  1. Objetivo Principal: Consolidar os resultados de todas as análises anteriores, aplicar o julgamento de especialistas (arquitetos, desenvolvedores seniores) para validar e refinar os limites modulares propostos, e estabelecer um processo iterativo.

4.5.1 Input:

  1. Outputs de todas as etapas anteriores (Bounded Contexts, grafos de dependência, métricas estáticas/dinâmicas, análise de co-mudança).

  2. Conhecimento e experiência da equipe de desenvolvimento e arquitetura do Evently.

4.5.2 Processo:

  1. Síntese das Evidências: Compilar e comparar os resultados das análises de domínio, estática, dinâmica e de evolução. Identificar áreas de concordância (onde todas as análises apontam para o mesmo limite) e áreas de conflito (onde diferentes análises sugerem limites distintos).

  2. Workshop de Validação: Apresentar as evidências e os limites modulares propostos à equipe. Discutir os pontos de conflito, considerar fatores não capturados pelas análises (ex: estratégia de negócio futura, conhecimento tácito da equipe, restrições tecnológicas específicas).

  3. Tomada de Decisão Arquitetural: Com base na síntese das evidências e na discussão da equipe, tomar decisões informadas sobre os limites finais dos módulos. Documentar as justificativas para essas decisões, especialmente onde elas divergem das sugestões puramente técnicas.

  4. Refinamento Iterativo: Reconhecer que a modularização não é um processo único. Planejar revisões periódicas dos limites modulares à medida que o sistema evolui, o domínio do negócio muda ou novas informações se tornam disponíveis. O feedback contínuo da equipe sobre a facilidade de trabalhar com os módulos (coesão percebida, acoplamento percebido) é crucial.

4.5.3 Output:

  1. Definição final e documentada dos módulos do Monólito Modular Evently, incluindo seus componentes internos e interfaces expostas.

  2. Justificativa das decisões arquiteturais tomadas.

  3. Plano para monitoramento e refinamento contínuo da modularidade.

4.5.4 Conexão com a Próxima Etapa e Métricas:

Esta etapa conclui o processo de identificação. A definição final dos módulos serve como base para a avaliação detalhada da qualidade (Seção 4) e para o trabalho de refatoração subsequente. A validação humana garante que as métricas e análises técnicas sejam interpretadas no contexto correto.