O Que É Coesão - Coesão textual: o que é, elementos, tipos - PrePara ENEM
Coesão textual: o que é, elementos, tipos - PrePara ENEM

O que é coesão e por que você se importa

Coesão é a medida em que os elementos internos de um módulo, classe ou componente compartilham uma responsabilidade única e bem definida. Não é um conceito filosófico — é uma métrica de design que você usa todo dia quando decide se movimenta funcionalidades de um lugar para outro no seu código. A definição de livro diz que alta coesão é boa e baixa coesão é ruim. A prática diz que é muito mais matizado do que isso, e a maioria dos projetos que eu vejo cair não cai por falta de coesão alta, mas sim por tentativa cega de aplicá-la sem considerar o custo real.

O que é coesão na prática

Vamos ao concreto. Imagine uma classe que chama API, valida dado, transforma JSON, salva no banco e ainda manda e-mail de notificação. Essa classe tem baixa coesão porque reúne cinco responsabilidades diferentes sob um mesmo nome. Cada mudança em um desses domínios exige abrir o mesmo arquivo, testar o mesmo método, revisar a mesma PR. Isso se torna um problema de manutenção mensurável. A versão coesa daquela situação seria dividir em uma classe de entrada (recebe a requisição e valida), uma de transformação, uma de persistência e uma de notificação. Cada uma com seu próprio critério de mudança. O princípio é simples. A aplicação depende de entender onde termina uma responsabilidade e começa outra.

Os tipos mais conhecidos são coesão funcional, sequencial, comunicacional, condicional, temporal, lógica e coincidente. Coesão coincidente é o pior caso: elementos agrupados por conveniência arbitrária, como colocar todas as funções utilitárias sem relação em uma só classe. Coesão funcional é o ideal: um único trabalho feito de forma completa e isolada. A maioria dos desenvolvedores consegue atingir nível comunicacional ou sequencial sem esforço. Alcançar nível funcional consistentemente exige decisão consciente e revisão. Eu trabalhei em um projeto onde tínhamos um serviço de processamento de pedidos que, além de calcular totais, também atualizava estoque, lia logs de terceiros e gerava relatório mensal. A classe era grande e ninguém assumia propriedade porque ninguém sabia qual era a função central. A solução não foi apenas separar em classes menores. Foi identificar qual era a responsabilidade verdadeiramente única que justificava a existência daquele domínio. No fim, cortamos geração de relatório e leitura de log para fora completamente. Sobrou um serviço focado em cálculo e confirmação de pedido. O tempo de revisão de PR caiu de cerca de quarenta minutos para quinze em média.

Pegadinhas que iniciantes ignoram

Primeira: coesão não é sinônimo de número pequeno de linhas. Você pode ter uma classe com trinta linhas extremamente coesa e outra com dez linhas fracamente coesa se as dez linhas fizerem coisas desconexas. Segundo: coesão alta demais, levada ao extremo, gera fragmentação onde cada operação precisa de dez classes para ser executada. Isso aumenta complexidade de orquestração e custo de teste de integração. O equilíbrio acontece quando a responsabilidade é única, mas o granular necessário para expressá-la é razoável dentro do contexto do domínio. Terceira: coesão e acoplamento precisam ser analisados juntos. Você pode aumentar a coesão de uma classe ao extrair responsabilidades, mas se essas novas classes dependem umas das outras de forma rígida, o ganho é ilusório. O projeto continua difícil de mudar, só que agora as mudanças se espalham por mais arquivos.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Como aplicar sem transformar o projeto em confusão

Comece mapeando as responsabilidades atuais. Escreva uma frase para cada classe ou módulo importante: "Esta parte existe para fazer X". Se a frase precisar de "e" ou "também", você já achou uma divisão. Depois, valide se a separação propõe interfaces claras. Dependência deve passar por contratos, não por acesso direto a detalhes internos. Use nomes que reflitam a responsabilidade única. Classe responsável por validar entrada não deve chamar ValidadorGenérico ou Helpers. Nomes genéricos são sinal de que o agrupamento foi feito por preguiça, não por domínio. Refatorações de coesão devem ser pequenas e reversíveis. Extração incremental funciona melhor do que reescrita em bloco. Cada passo precisa manter o sistema passando nos testes existentes.

Em linguagens dinâmicas e scripts rápidos, a obsessão por coesão pode ter custo maior que o benefício. Eu já vi time cortar uma função utils de doze linhas em quatro classes diferentes e perder duas horas em uma tarefa que não justificava tal investimento. A regra prática é: aplique o critério de coesão quando a taxa de mudança no módulo for alta ou quando o tempo de leitura e revisão superar o custo de separação.

Quando coesão não resolve o problema

Coesão não substitui bom design de domínio, não corrige má escolha de arquitetura e não compensa testes ausentes. Projeto com baixo coesão mas com testes abrangentes ainda será mais resiliente do que projeto com coesão alta e sem cobertura. Também não adianta aplicar em código legítimo de script único ou em protótipo descartável. Nesses casos, a complexidade de separação só adiciona atrito. Se você está travado entre manter tudo junto para velocidade imediata ou refatorar para coesão, considere a alternativa de isolamento por camadas em vez de refatoração profunda. Criar uma camada de adaptação que separa entrada, processamento e saída pode dar parte do ganho sem o custo completo da divisão total. Funciona bem em sistemas onde a mudança de domínio ainda é incerta.

Resumo prático: alta coesão significa que cada parte do seu sistema responde a um único motivo de mudança. Verifique isso escrevendo a responsabilidade em uma frase, revisando nomes, separando responsabilidades de forma incremental e validando que interfaces permanecem claras. O resultado costuma ser revisão mais rápida, erro mais isolado e código que muda sem quebrar tudo ao redor.