Pular para o conteúdo
12 min de leitura

Acoplamento e coesão explicados de forma simples

Por Lucas Andrade ·

Entenda acoplamento e coesão sem jargão: por que o que muda junto deve ficar junto, por que módulos devem depender pouco uns dos outros e como isso muda tudo.

Neste artigo

Existem duas palavras que aparecem em quase toda conversa séria sobre arquitetura de software, e que quase nunca são explicadas de um jeito que alguém de fora entenderia: acoplamento e coesão. Elas soam acadêmicas, distantes, coisa de livro grosso. Mas por trás dos termos há uma ideia extraordinariamente simples e prática, uma ideia que, quando você a enxerga, muda a forma como você lê e escreve código para sempre. A qualidade de um sistema — o quanto ele resiste à mudança, o quanto é agradável de testar, o quanto uma pessoa nova consegue entendê-lo — depende quase que diretamente de como essas duas forças estão equilibradas.

A intuição central é esta: coesão fala de como as coisas dentro de uma parte se relacionam, e acoplamento fala de como partes diferentes dependem umas das outras. Queremos coesão alta e acoplamento baixo. Queremos que cada peça do sistema tenha um propósito claro e concentrado, e que as peças conversem entre si pelo mínimo necessário. Um sistema com essa propriedade se comporta como uma boa cidade: bairros com identidade própria, ligados por poucas avenidas bem definidas, em vez de um emaranhado onde tudo depende de tudo.

Neste artigo vamos desmontar cada um desses conceitos com calma, olhar os tipos de acoplamento do mais saudável ao mais perigoso, entender por que baixo acoplamento facilita tanto a mudança e o teste, e passar por analogias concretas — do Lego aos fios embolados atrás da TV — que fixam a ideia. Ao final, você terá uma bússola prática para decidir onde colocar código e o que separar do quê.

O que é coesão, de verdade#

Coesão é a medida de quão relacionadas e focadas estão as responsabilidades dentro de um único módulo, classe ou função. Um módulo altamente coeso faz uma coisa e faz bem: todas as suas partes existem para servir a um mesmo propósito. Um módulo de baixa coesão é um balde de coisas que só estão juntas por acaso histórico — porque alguém precisou de um lugar para colocar uma função e aquele arquivo estava aberto.

Pense em uma gaveta de cozinha. Uma gaveta coesa guarda talheres: garfos, facas, colheres. Você sabe exatamente o que encontrar ali e onde guardar um novo item. Uma gaveta incoesa é a famosa "gaveta da bagunça", onde convivem pilhas, chaves de fenda, elásticos, manuais e um carregador antigo. Ela funciona, num sentido pobre da palavra, mas achar qualquer coisa exige revirar tudo, e ninguém sabe se um objeto novo pertence ali ou não.

No código, a alta coesão se manifesta quando você olha para um arquivo e as funções ali dentro claramente pertencem umas às outras. Um módulo de cálculo de impostos que só tem regras de imposto é coeso. Se ele também formata datas, envia e-mails e lê arquivos de configuração, a coesão despencou. O sintoma prático da baixa coesão é que você não consegue descrever o que o módulo faz sem usar a palavra "e" várias vezes: "ele calcula impostos e manda e-mail e gera PDF e valida CPF".

A boa heurística, quase um mantra, é: o que muda junto deve ficar junto. Se duas regras de negócio tendem a mudar pela mesma razão, no mesmo momento, por decisão da mesma pessoa, elas provavelmente pertencem ao mesmo lugar. Se mudam por razões diferentes, em ritmos diferentes, provavelmente deveriam estar separadas. Coesão bem feita não é sobre proximidade física de linhas — é sobre proximidade de propósito.

O que é acoplamento#

Se coesão olha para dentro, acoplamento olha para as pontes entre as ilhas. Acoplamento é o grau de dependência entre módulos: o quanto um precisa saber sobre o outro para funcionar. Sempre que uma parte do sistema conhece detalhes internos de outra, chama seus métodos específicos, depende de sua estrutura de dados ou assume como ela funciona por dentro, existe acoplamento.

Algum acoplamento é inevitável e desejável — módulos precisam colaborar, senão não formam um sistema, apenas um monte de pedaços isolados. O problema não é existir dependência; é a dependência ser mais forte, mais íntima e mais espalhada do que precisaria ser. Quando o acoplamento é alto, mexer numa parte obriga a mexer em várias outras. O sistema fica rígido: qualquer mudança encontra resistência, porque cutuca uma teia de conexões escondidas.

A imagem clássica para acoplamento baixo é a peça de Lego. Cada bloco expõe uma interface padronizada e simples — aqueles pinos no topo. Um bloco não sabe nada sobre o interior de outro; ele só precisa encaixar. Você pode trocar um bloco vermelho por um azul do mesmo formato sem que o resto da construção perceba. Agora imagine o oposto: peças de Lego coladas com supercola e ainda soldadas por dentro. Trocar uma exige quebrar as vizinhas. Isso é acoplamento alto, e boa parte do software do mundo se parece mais com a caixa de peças coladas do que com o Lego limpo.

Os tipos de acoplamento, do saudável ao tóxico#

Nem todo acoplamento é igual. Décadas de estudo produziram uma escala útil, que vale conhecer porque ela treina o olho a distinguir uma dependência aceitável de uma perigosa.

  • Acoplamento por dados: a forma mais leve e saudável. Um módulo passa a outro apenas os dados simples de que ele precisa — um número, um nome, um valor. Nada de segredos internos, nada de "por sinal, também mexe nesse outro campo aqui". É a conversa mínima e explícita, e é a que devemos buscar.
  • Acoplamento por controle: um módulo passa a outro uma informação que controla o comportamento interno dele — um sinalizador do tipo "faça o modo A em vez do modo B". Aqui o chamador precisa saber como o chamado decide as coisas por dentro, o que já é uma intimidade indesejada. Muitas vezes indica que deveriam ser dois métodos distintos, não um com um interruptor.
  • Acoplamento global: dois módulos compartilham um estado global — uma variável, um singleton, uma configuração mutável acessível de qualquer lugar. Parece conveniente, mas cria dependências invisíveis: mudar o global afeta todo mundo que o toca, e ninguém consegue prever quem toca. É a origem de bugs fantasma que só aparecem quando duas partes do sistema pisam no mesmo estado.
  • Acoplamento por conteúdo: o mais tóxico. Um módulo enfia a mão no interior do outro, altera seus dados privados ou depende de detalhes de implementação que deveriam ser invisíveis. É como um vizinho que entra pela janela e reorganiza seus móveis. Qualquer mudança interna do módulo invadido quebra o invasor, e essa quebra é silenciosa e difícil de rastrear.

A regra de ouro que emerge dessa escala: prefira sempre a forma mais fraca de acoplamento que resolve o problema. Passe dados, não sinalizadores de controle. Evite estado global. E jamais dependa dos órgãos internos de outro módulo — dependa apenas do que ele promete publicamente.

Por que baixo acoplamento facilita mudar e testar#

Aqui está o coração prático de tudo. A razão pela qual perseguimos baixo acoplamento não é estética; é econômica. Software passa a maior parte da vida sendo modificado, não escrito pela primeira vez. E o custo de uma mudança é diretamente proporcional a quantas outras coisas ela obriga a tocar.

Num sistema fortemente acoplado, cada alteração dispara um efeito bola de neve. Você muda um campo para corrigir um bug, e isso quebra o módulo vizinho que assumia o formato antigo. Você conserta o vizinho, e isso quebra um terceiro. A correção de uma linha vira um mutirão de dois dias, e cada rodada de conserto tem chance de introduzir um novo defeito. O medo de mexer se instala, e o time começa a evitar melhorias, deixando o código apodrecer porque tocá-lo dói demais.

Num sistema com baixo acoplamento acontece o oposto. A mudança fica contida: você abre o módulo responsável, ajusta, e o resto do sistema nem percebe, porque só dependia da promessa pública, que continuou a mesma. A confiança para melhorar volta. Refatorar deixa de ser assustador.

O teste é o outro grande beneficiário, e talvez o mais imediato. Para testar um módulo isoladamente, você precisa conseguir colocá-lo numa bancada sozinho. Se ele está soldado a um banco de dados real, a um serviço externo, a um relógio do sistema, você não consegue — precisa erguer o mundo inteiro só para exercitar uma regrinha. Com baixo acoplamento, você substitui as dependências reais por dublês simples durante o teste, alimenta entradas controladas e verifica saídas. O teste fica rápido, determinístico e fácil de escrever. Não é coincidência que código difícil de testar seja quase sempre código fortemente acoplado: a dificuldade de testar é o sintoma que o acoplamento excessivo produz primeiro.

A Lei de Deméter: não fale com estranhos#

Existe um princípio prático que ajuda enormemente a manter o acoplamento sob controle, e ele tem um nome curioso: a Lei de Deméter, ou "princípio do menor conhecimento". Em linguagem simples, ela diz: fale apenas com seus amigos imediatos, não com os amigos dos seus amigos.

Na prática, isso significa desconfiar de cadeias longas de acesso, aquelas em que você pega um objeto, dele pega outro, dele pega um terceiro e então age sobre o terceiro. Cada elo dessa corrente é uma suposição sobre a estrutura interna de outra coisa. Quando você navega fundo por dentro de objetos alheios, seu código passa a depender de toda a topografia daquele caminho — e qualquer reorganização em qualquer ponto o quebra.

A ideia da lei é que cada objeto deveria pedir o que precisa ao seu vizinho direto e deixar que ele cuide de seus próprios detalhes internos. Em vez de alcançar lá no fundo para buscar algo você mesmo, você pede: "me dê o resultado". O vizinho decide como obtê-lo. Isso reduz o número de coisas que seu código conhece, e conhecer menos é depender de menos. Seguir Deméter não é uma regra rígida a aplicar cegamente, mas um cheiro útil: cadeias longas de pontos costumam sinalizar acoplamento se infiltrando.

Como aumentar a coesão na prática#

Se a baixa coesão é uma gaveta bagunçada, aumentá-la é o ato de organizar. Alguns movimentos concretos ajudam a levar um módulo disperso de volta ao foco.

  • Separe por razão de mudança. Pergunte de cada função: por que ela mudaria, e por quem? Funções que respondem a razões diferentes — uma muda quando a regra fiscal muda, outra quando o layout do relatório muda — pertencem a lugares diferentes. Agrupe por motivo, não por semelhança superficial.
  • Extraia o que destoa. Se um módulo de domínio está fazendo trabalho de infraestrutura — falando com arquivos, formatando saída, chamando rede — extraia esse trabalho para um colaborador dedicado. O módulo volta a ter um só assunto.
  • Nomeie honestamente. Um bom teste de coesão é tentar dar ao módulo um nome que descreva tudo que ele faz. Se o nome honesto vira uma lista com vários "e", o módulo está pedindo para ser dividido. Um nome preciso e único é sinal de coesão saudável.
  • Deixe o que muda junto vizinho. Ao contrário: se você percebe que sempre edita dois arquivos distantes na mesma tarefa, talvez eles devessem estar mais próximos. A coesão também é sobre reunir o que a realidade insiste em manter unido.

Aumentar coesão e reduzir acoplamento andam de mãos dadas. Quando você concentra cada responsabilidade no seu devido lar, as fronteiras entre módulos ficam naturais, e as conversas entre eles se resumem ao essencial. Um sistema coeso por dentro tende a ser pouco acoplado por fora quase como consequência.

As duas forças trabalhando juntas#

Vale insistir que coesão e acoplamento não são metas independentes; são dois lados da mesma moeda de organização. Quando você agrupa mal — junta o que não pertence — cria baixa coesão dentro do módulo e aumenta o acoplamento para fora, porque agora esse módulo confuso precisa conversar com muitos outros para dar conta de suas responsabilidades dispersas. Quando você agrupa bem, os dois indicadores melhoram ao mesmo tempo: cada peça é focada por dentro e conversa pouco por fora.

Pense de novo nos fios atrás da estante da TV. Quando cada aparelho tem seus cabos organizados e etiquetados, ligados apenas ao que precisam, trocar um deles é trivial: você segue o fio, desliga, encaixa o novo. Quando tudo vira um novelo emaranhado — cabos cruzando sem critério, ninguém sabendo o que vai aonde — mexer em um puxa três outros, e você tem medo de desligar qualquer coisa. Software é exatamente esse novelo, tornado invisível. Coesão e acoplamento são as ferramentas conceituais para mantê-lo desembaraçado.

Conclusão#

Acoplamento e coesão parecem termos áridos, mas descrevem uma verdade cotidiana de quem constrói software: sistemas fáceis de mudar são feitos de partes focadas que dependem pouco umas das outras. Alta coesão significa que cada módulo faz uma coisa clara, reunindo o que muda junto. Baixo acoplamento significa que as partes conversam pelo mínimo necessário, através de promessas públicas em vez de intimidades internas.

Não busque isso por purismo, mas porque o custo real do software está na mudança, e a mudança fica barata exatamente quando ela se mantém contida. Da próxima vez que abrir um arquivo, faça duas perguntas simples: as coisas aqui dentro realmente pertencem umas às outras? E o quanto este pedaço precisa saber sobre os outros para funcionar? As respostas vão apontar, com uma clareza surpreendente, onde estão as gavetas bagunçadas e os novelos de fios que um dia vão custar caro. Reorganizá-los cedo, enquanto ainda é fácil, é uma das decisões mais rentáveis que um time pode tomar.

Leituras relacionadas

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly