Princípios SOLID em Java: teoria e prática avançada

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 avançada



Os princípios SOLID são a base do design orientado a objetos, que ajuda desenvolvedores a criar código resistente a mudanças, facilmente testável e escalável. Para um desenvolvedor Java, entender esses princípios em nível avançado não é apenas conhecer as definições, mas saber identificar suas violações em código legado e aplicar padrões para refatoração. Neste artigo, analisaremos cada princípio com foco em situações complexas, porém típicas.



1. Single Responsibility Principle (SRP): A linha entre responsabilidade e coesão



Teoria: Uma classe deve ter apenas um motivo para mudar. Na prática, isso significa que a classe deve ser responsável por uma parte da funcionalidade do programa.



Prática avançada: Frequentemente, a violação do SRP não se manifesta em uma mistura explícita de lógicas, mas em uma responsabilidade "difusa". Considere o exemplo de uma classe para trabalhar com relatórios:



// Violação do SRP: a classe lida com dados, formatação e enviopublic class ReportService {    public void generateReport(List<Data> data) {        // Lógica de cálculos        Map<String, Integer> aggregated = aggregate(data);        // Formatação (HTML)        String html = formatToHtml(aggregated);        // Envio por email        sendEmail(html, "admin@example.com");    }

private Map<String, Integer> aggregate(List<Data> data) { // ... return new HashMap<>(); }

private String formatToHtml(Map<String, Integer> data) { // ... return "<html>...</html>"; }

private void sendEmail(String content, String to) { // ... }}


Problema: se o formato do relatório mudar (precisar de PDF em vez de HTML), essa classe terá que ser alterada. Se o método de envio mudar (Telegram em vez de email) — novamente. Solução — dividir em três classes:



public class ReportAggregator {    public Map<String, Integer> aggregate(List<Data> data) { ... }}

public class HtmlReportFormatter { public String format(Map<String, Integer> data) { ... }}

public class EmailSender { public void send(String content, String to) { ... }}

// Composição no serviçopublic class ReportGenerationFacade { private ReportAggregator aggregator; private HtmlReportFormatter formatter; private EmailSender sender;

public void generateAndSend(List<Data> data) { var aggregated = aggregator.aggregate(data); var html = formatter.format(aggregated); sender.send(html, "admin@example.com"); }}


2. Open-Closed Principle (OCP): A arte da extensão através de abstrações



Teoria: As classes devem estar abertas para extensão, mas fechadas para modificação.



Prática avançada: Uma violação típica são cadeias de if-else ou switch para diferentes tipos de objetos. A maneira avançada é usar o padrão Strategy ou Template Method com polimorfismo.



// Violação do OCP: ao adicionar um novo tipo de pagamento, é preciso alterar a classepublic class PaymentProcessor {    public void processPayment(String type, double amount) {        if ("CREDIT_CARD".equals(type)) {            // lógica para cartão de crédito        } else if ("PAYPAL".equals(type)) {            // lógica para PayPal        } else if ("BITCOIN".equals(type)) {            // lógica para Bitcoin        }    }}


Correção através de interface e fábrica:



public interface PaymentMethod {    void pay(double amount);}

public class CreditCardPayment implements PaymentMethod { public void pay(double amount) { ... }}

public class PayPalPayment implements PaymentMethod

Blogs

Book Recommendations