Princípios SOLID
SOLID são cinco princípios de design orientado a objetos que tornam o código mais flexível, legível e fácil de manter. Cada letra representa um princípio fundamental.
SRP — Canivete Suíço vs Ferramentas Dedicadas
Um canivete suíço faz tudo, mas nada muito bem. Ferramentas dedicadas (chave de fenda, alicate, martelo) fazem uma coisa com excelência. Uma classe deve ter apenas uma responsabilidade — um motivo para mudar.
S — Single Responsibility Principle
Cada classe deve ter apenas uma razão para mudar. Se uma classe cuida de validação E de persistência, ela tem duas responsabilidades e deve ser separada em duas.
OCP — Tomada com Adaptador
Você não quebra a parede para mudar a tomada — usa um adaptador. O código deve ser aberto para extensão (plugar adaptador) mas fechado para modificação (não mexer na fiação interna).
O — Open/Closed Principle
Módulos devem ser abertos para extensão e fechados para modificação. Use interfaces e abstrações para adicionar comportamento novo sem alterar código existente.
LSP — Controle Remoto Universal
Um controle remoto universal funciona com qualquer TV. Se você trocar a TV Samsung por uma LG, o controle continua funcionando. Subclasses devem poder substituir suas classes base sem quebrar o sistema.
L — Liskov Substitution Principle
Se uma classe B herda de A, você deve poder usar B em qualquer lugar que espera A sem comportamento inesperado. Exemplo clássico: Quadrado não deveria herdar de Retângulo se mudar o comportamento de redimensionar.
ISP — Cardápio vs Buffet
No cardápio, você vê só o que pode pedir na categoria escolhida. No buffet, tudo está exposto mesmo que você não queira. Interfaces devem ser específicas — ninguém deve ser forçado a implementar métodos que não usa.
I — Interface Segregation Principle
Prefira várias interfaces pequenas e específicas a uma interface grande e genérica. Cada cliente deve depender apenas dos métodos que realmente utiliza.
DIP — Plugue na Tomada, Não Fio Soldado
Se o carregador do celular fosse soldado na parede, trocar de carregador seria um pesadelo. O plugue (interface) permite trocar facilmente. Módulos de alto nível não devem depender de implementações concretas — ambos devem depender de abstrações.
D — Dependency Inversion Principle
Dependa de abstrações, não de implementações concretas. Ao invés de instanciar dependências diretamente, receba-as por injeção — isso facilita testes e troca de implementações.