Princípios SOLID em Java: guia completo da teoria ao código

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Princípios SOLID em Java: da teoria à prática

SOLID é um acrônimo de cinco princípios fundamentais da programação orientada a objetos, formulados por Robert Martin (Uncle Bob). Esses princípios ajudam os desenvolvedores a criar código flexível, sustentável e facilmente extensível. Neste artigo, vamos analisar cada princípio SOLID com exemplos em Java, desde a teoria simples até a prática real.



1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única

Teoria: Uma classe deve ter apenas um motivo para mudar. Em outras palavras, cada classe deve ser responsável por exatamente uma funcionalidade.

Violação do SRP:

public class Employee {    public void calculatePay() { /* cálculo do salário */ }    public void saveToDatabase() { /* salvar no BD */ }    public void generateReport() { /* gerar relatório */ }}

Correção:

public class Employee { /* apenas dados */ }

public class PayCalculator { public void calculatePay(Employee emp) { /* ... */ }}

public class EmployeeRepository { public void save(Employee emp) { /* ... */ }}

public class ReportGenerator { public void generate(Employee emp) { /* ... */ }}

Agora cada classe tem uma responsabilidade clara, o que simplifica os testes e a manutenção.



2. Open-Closed Principle (OCP) — Princípio Aberto/Fechado

Teoria: Entidades de software (classes, módulos, funções) devem estar abertas para extensão, mas fechadas para modificação.

Violação do OCP:

public class ShapeDrawer {    public void draw(String shapeType) {        if ("circle".equals(shapeType)) {            // desenhar círculo        } else if ("rectangle".equals(shapeType)) {            // desenhar retângulo        }    }}

Correção usando polimorfismo:

public interface Shape {    void draw();}

public class Circle implements Shape { @Override public void draw() { /* desenhar círculo */ }}

public class Rectangle implements Shape { @Override public void draw() { /* desenhar retângulo */ }}

public class ShapeDrawer { public void draw(Shape shape) { shape.draw(); }}

Agora, para adicionar uma nova forma (por exemplo, Triangle), não é necessário alterar o código existente — basta criar uma nova classe que implemente a interface Shape.



3. Liskov Substitution Principle (LSP) — Princípio da Substituição de Liskov

Teoria: Os objetos em um programa devem ser substituíveis por instâncias de seus subtipos sem alterar a correção do programa. Se S é um subtipo de T, então objetos do tipo T podem ser substituídos por objetos do tipo S sem quebrar o funcionamento.

Violação clássica do LSP:

public class Rectangle {    protected int width, height;    public void setWidth(int w) { width = w; }    public void setHeight(int h) { height = h; }    public int getArea() { return width * height; }}

public class Square extends Rectangle { @Override public void setWidth(int w) { super.setWidth(w); super.setHeight(w); } @Override public void setHeight(int h) { super.setWidth(h); super.setHeight(h); }}

Um cliente que trabalha com Rectangle espera que alterar a largura não afete a altura. O quadrado viola essa expectativa. Solução: Usar uma interface comum ou classes separadas sem herança.



4. Interface Segregation Principle (ISP) — Princípio da Segregação de Interfaces

Teoria: Os clientes não devem depender de métodos que não usam. É melhor ter várias interfaces especializadas do que uma interface "gorda".

Violação do ISP:

                

Blogs

Book Recommendations