Padrões de Projeto em Java: guia completo com exemplos
Padrões de projeto (design patterns) são soluções comprovadas para problemas típicos que surgem no desenvolvimento de software. Em Java, esses padrões são especialmente requisitados devido ao paradigma estrito de orientação a objetos da linguagem. O uso de padrões permite tornar o código mais flexível, sustentável e escalável.
Neste artigo, abordaremos três grupos principais de padrões de projeto em Java: criacionais, estruturais e comportamentais. Cada padrão será acompanhado por um exemplo prático de código.
Padrões Criacionais (Creational Patterns)
Os padrões criacionais gerenciam o processo de criação de objetos, tornando o sistema independente da forma como eles são construídos. Vamos considerar dois dos padrões mais populares: Singleton e Factory Method.
Singleton (Singleton)
O Singleton garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela. Este padrão é frequentemente usado para conexões com bancos de dados, logging ou caching.
Exemplo de implementação de um Singleton thread-safe em Java:
public class DatabaseConnection { private static volatile DatabaseConnection instance; private String connectionString;
private DatabaseConnection(String connectionString) { this.connectionString = connectionString; }
public static DatabaseConnection getInstance(String connectionString) { if (instance == null) { synchronized (DatabaseConnection.class) { if (instance == null) { instance = new DatabaseConnection(connectionString); } } } return instance; }
public void connect() { System.out.println("Conectando a " + connectionString); }}Uso:
DatabaseConnection db = DatabaseConnection.getInstance("jdbc:mysql://localhost:3306/mydb");db.connect();Factory Method (Factory Method)
O Factory Method define uma interface para criar um objeto, mas permite que as subclasses alterem o tipo do objeto criado. Isso permite delegar a criação de instâncias para classes filhas.
Exemplo de um factory method para criar diferentes tipos de notificações:
interface Notification { void send(String message);}
class EmailNotification implements Notification { public void send(String message) { System.out.println("Enviando email: " + message); }}
class SMSNotification implements Notification { public void send(String message) { System.out.println("Enviando SMS: " + message); }}
abstract class NotificationFactory { public abstract Notification createNotification();
public void notifyUser(String message) { Notification notification = createNotification(); notification.send(message); }}
class EmailNotificationFactory extends NotificationFactory { public Notification createNotification() { return new EmailNotification(); }}
class SMSNotificationFactory extends NotificationFactory { public Notification createNotification() { return new SMSNotification(); }}Uso:
NotificationFactory factory = new EmailNotificationFactory();factory.notifyUser("Seu pedido foi confirmado!");Padrões Estruturais (Structural Patterns)
Os padrões estruturais descrevem maneiras de combinar classes e objetos para formar estruturas maiores. Vamos considerar o padrão Adapter (Adapter).
Adapter (Adapter)
O Adapter permite que objetos com interfaces incompatíveis trabalhem juntos. Ele encapsula um objeto, fornecendo a interface necessária para o cliente.
Exemplo de um adapter para integrar um sistema de logging antigo
```