Ao organizar o serviço do Mishkan, a Torá designa cada família a uma tarefa específica: cada um em seu próprio trabalho, com sua carga definida, sem invadir a do outro. A ordem não é burocracia; é o que permite o todo funcionar sem colisão. Código é igual. Quando uma classe faz de tudo, qualquer mudança nela arrisca quebrar tudo o que ela toca, e o medo de mexer congela a evolução. SOLID, os cinco princípios que Robert C. Martin popularizou, existe para dar a cada peça do código o seu próprio trabalho, uma responsabilidade clara, uma razão só para mudar. É a disciplina que mantém o software maleável em vez de deixá-lo apodrecer até ninguém ter coragem de tocá-lo.
01Por que o código apodrece, e o que o mantém macio
Todo sistema começa limpo e tende à degradação. A cada prazo apertado, uma classe ganha mais uma responsabilidade, um método fica mais comprido, uma dependência é adicionada às pressas. Sozinha, cada decisão é pequena; somadas, elas produzem o código rígido, frágil e imóvel que Robert C. Martin descreveu: rígido porque mudar uma coisa exige mudar muitas, frágil porque a mudança quebra o que não tinha relação, imóvel porque nada é reaproveitável fora do emaranhado. SOLID nasceu como o antídoto para essa entropia, não como enfeite acadêmico.
Os cinco princípios têm um objetivo comum: gerenciar a dependência entre as partes, para que a mudança fique contida. Não são regras para decorar; são heurísticas para responder a uma pergunta prática, quando esta mudança chegar, quantas coisas ela vai obrigar a mexer? Código que segue SOLID responde poucas; código que o ignora responde muitas, e é aí que nasce o medo de mexer. A meta final não é elegância, é a capacidade de mudar o sistema com confiança, que é o que separa o software vivo, que evolui, do software fóssil, que só se substitui.
Figura 1Os cinco princípios do SOLID
SResponsabilidade únicacada classe tem uma razão só para mudar
OAberto-fechadoaberto para estender, fechado para modificar
LSubstituição de Liskovo subtipo honra o contrato do tipo base
ISegregação de interfaceinterfaces pequenas, ninguém depende do que não usa
DInversão de dependênciadepender de abstração, não de implementação
GOALO objetivo comumconter a mudança, para mexer sem medo
Popularizados por Robert C. Martin. Não são regras para decorar, são heurísticas para uma pergunta prática: quando a mudança chegar, quantas coisas ela obriga a mexer? Menos é melhor.
02A responsabilidade única é o coração de tudo
Dos cinco, o primeiro é o mais importante e o mais mal compreendido. Responsabilidade única não quer dizer que a classe faz uma coisa só; quer dizer que ela tem uma razão só para mudar, que ela responde a um só ator ou motivo de negócio. A classe que gera o relatório e também o formata em PDF e também o envia por e-mail tem três razões para mudar, três donos diferentes puxando-a em direções diferentes, e cada mudança de um arrisca quebrar o do outro. Separá-la em três, cada uma com um trabalho, é dar a cada um o seu próprio serviço, como as famílias do Mishkan.
O princípio é sobre coesão: manter junto o que muda junto, e separar o que muda por razões diferentes. É o mesmo instinto que faz uma boa organização não misturar o financeiro com o jurídico, não porque uma seja melhor, mas porque respondem a lógicas distintas. Código coeso é fácil de entender, porque cada peça tem um propósito nomeável; é fácil de testar, porque faz pouca coisa; e é fácil de mudar, porque a mudança tem endereço. Quando alguém pergunta o que esta classe faz e a resposta honesta tem um e depois um e depois um outro, a responsabilidade única já foi violada, e a próxima mudança vai doer.
Figura 2Uma classe que faz tudo, separada por razão de mudar
Gera o relatório regra de negóciomuda quando a lógica de negócio muda; dono: o negócio
Formata o PDF apresentaçãomuda quando o layout muda; dono: o design
Envia por e-mail infraestruturamuda quando o meio de envio muda; dono: a infra
Cada uma isolada coesãouma razão de mudar cada, e a mudança tem endereço
Responsabilidade única não é fazer uma coisa só, é ter uma razão só para mudar. Manter junto o que muda junto e separar o que muda por razões diferentes: coesão, o coração do SOLID.
03Estender sem modificar, depender do abstrato
O aberto-fechado e a inversão de dependência trabalham juntos e são o que dá ao software a capacidade de crescer sem se quebrar. Aberto-fechado diz que você deve poder adicionar comportamento novo sem alterar o código que já funciona: aberto para extensão, fechado para modificação. Na prática, isso significa que a variação vive atrás de uma abstração, e o novo caso entra como uma implementação nova, não como mais um if no meio do código antigo que já foi testado e está em produção.
A inversão de dependência é o mecanismo que torna isso possível: em vez de o código de alto nível, a regra de negócio, depender do código de baixo nível, o banco, o serviço externo, os dois dependem de uma abstração no meio. A regra de negócio declara preciso de um repositório, sem saber se é Postgres ou memória; a implementação concreta é injetada de fora. Isso inverte a seta de dependência, e o ganho é enorme: a regra de negócio, o que mais importa e menos deveria mudar, deixa de ser refém de detalhes de infraestrutura que mudam o tempo todo. É o mesmo princípio que a arquitetura hexagonal levaria ao extremo, e a semente dele mora aqui, no D do SOLID.
Figura 3Inversão de dependência: a regra de negócio deixa de ser refém do detalhe
01Sem inversãoa regra de negócio chama direto o banco concreto
02O problematrocar o banco obriga a mexer na regra de negócio
03Definir a abstraçãoa regra declara 'preciso de um repositório', uma interface
04IAInjetar o concretoa implementação real é passada de fora, não conhecida por dentro
05Estender sem modificarbanco novo é implementação nova, sem tocar na regra testada
↺ A seta de dependência inverte: a regra de negócio, o que mais importa, deixa de depender do detalhe de infraestrutura que mais muda.
Aberto-fechado e inversão de dependência juntos: a variação vive atrás de uma abstração, e o novo caso entra como implementação nova, não como mais um if no código já testado.
04Honrar o contrato e não obrigar o que não se usa
A substituição de Liskov e a segregação de interface cuidam de que as abstrações não mintam. Liskov diz que um subtipo tem que poder substituir o tipo base sem surpresa: se o código espera uma Ave e chama voar, um Pinguim que herda de Ave e quebra ao voar viola o princípio, porque o subtipo não honra o contrato que prometeu. A herança que parece natural mas quebra a expectativa é uma das fontes mais sutis de bug, e Liskov é o teste mental que a pega: o subtipo pode mesmo fazer tudo o que o tipo base promete?
A segregação de interface ataca o outro lado: interfaces gordas obrigam quem as implementa a carregar o que não usa. Uma interface com vinte métodos força cada implementação a lidar com os vinte, mesmo que precise de três, e cria acoplamento onde não deveria haver. A solução é quebrar em interfaces pequenas e focadas, para que cada cliente dependa só do que de fato usa. Os dois princípios, juntos, garantem que a abstração seja honesta: que o contrato prometido seja cumprido, e que ele não peça mais do que o necessário. É a diferença entre uma abstração que ajuda e uma que atrapalha disfarçada de organização.
Figura 4Liskov e segregação de interface: abstrações que não mentem
Princípio
O que exige
A violação típica
O sintoma
Substituição de Liskov
o subtipo honra o contrato do base
Pinguim herda de Ave e quebra ao voar
if 'se for pinguim' espalhado pelo código
Segregação de interface
interfaces pequenas e focadas
uma interface com vinte métodos
implementações que lançam 'não suportado'
Juntos
abstração honesta e enxuta
herança forçada e interface gorda
acoplamento onde não deveria existir
Os dois garantem que a abstração não minta: que o contrato prometido seja cumprido (Liskov) e que não peça mais do que o necessário (segregação). Abstração desonesta atrapalha disfarçada de organização.
05Aplicar sem virar dogma, e o que SOLID sustenta
SOLID amadurece do desconhecimento ao julgamento. No começo é o código sem princípio, que apodrece. Depois vem a fase perigosa: o entusiasta que aplica os cinco em tudo, criando uma interface para cada classe e uma abstração para cada variação imaginária, e produz um emaranhado de indireção pior que o problema original. No topo está o julgamento: aplicar SOLID onde a mudança é provável e o custo da rigidez é alto, e deixar simples o que é estável e pequeno. O melhor engenheiro não é o que aplica mais princípios, é o que sabe quando cada um paga o próprio custo.
Porque SOLID tem custo: cada abstração é uma indireção a mais para entender, e abstração criada para flexibilidade que nunca é exercida é complexidade pura, sem retorno. A regra que eu levo é aplicar o princípio quando a dor que ele previne já apareceu ou é claramente iminente, não por profilaxia dogmática. SOLID é a fundação de tudo o que vem depois neste eixo, os design patterns, a arquitetura limpa, o DDD, todos assentam sobre a ideia de dar a cada peça o seu próprio trabalho e gerenciar a dependência entre elas. Mas fundação é meio, não fim: o fim é o software que muda sem medo, e às vezes o caminho mais direto para ele é a simplicidade, não mais um princípio.
Figura 5Maturidade na aplicação do SOLID
0Sem princípioclasse que faz tudo, mudança que quebra tudo
1Conhecesabe nomear os cinco, mas não sente onde aplicar
2Dogmáticoaplica em tudo, cria indireção pior que o problema
3Seletivoaplica onde a mudança é provável e a rigidez dói
4Com julgamentopesa o custo da abstração contra o risco de não tê-la
5Invisívelo código muda sem medo, e ninguém precisa citar SOLID
A fase 2 é a armadilha: o dogmático produz indireção pior que o problema. O melhor engenheiro não aplica mais princípios, sabe quando cada um paga o próprio custo. Fundação é meio, não fim.
Para levar
SOLID dá a cada peça do código o seu próprio trabalho, como as famílias do Mishkan, para que a mudança fique contida e o software não apodreça. A responsabilidade única é o coração, uma razão só para mudar; aberto-fechado e inversão de dependência deixam o código crescer sem se quebrar; Liskov e segregação garantem que a abstração não minta. Mas o princípio tem custo, e a maturidade está em aplicá-lo onde a dor é real, não por dogma. A IA aponta a violação e o excesso. O fim, porém, não é seguir os cinco, é o software que muda sem medo, e às vezes o caminho é a simplicidade.
Tags
#julianovincedecampos
#SOLID
#Engenharia
#DesignDeSoftware
#OrientaçãoAObjetos
#CleanCode
#Arquitetura
Quem escreve: Juliano Vince de Campos
Gerente de Operações, Tecnologia e Infraestrutura (SRE) numa central de registros. Trabalho com tecnologia desde 2009 e com cibersegurança em tempo integral desde 2015, em infraestrutura crítica, fintech e banking. Escrevo sobre o que eu opero: confiabilidade, segurança, governança e IA que passa por gate antes de chegar em produção.