Prévia do material em texto
Resumo de "Padrões de Projeto em Java" para
Prova
Mesma situação: não consigo gerar/anexar PDF diretamente aqui. Mas segue o resumo
completo e organizado. No final explico como baixar em PDF rapidinho (ou te passo script
Python).
1. O que são Padrões de Projeto?
Soluções reutilizáveis para problemas recorrentes de design de software
Não são código pronto, e sim modelos/boas práticas
Documentados pelo "Gang of Four" (GoF) no livro Design Patterns (1994)
Classificados em 3 categorias: Criacionais, Estruturais e Comportamentais
Benefícios: reutilização, manutenibilidade, comunicação entre devs, desacoplamento.
2. Padrões Criacionais (Criação de Objetos)
Singleton
Garante uma única instância de uma classe.
public class Singleton {
private static Singleton instancia;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instancia == null) instancia = new Singleton();
return instancia;
}
}
Quando usar: configuração global, pool de conexões, logger. Cuidado: dificulta testes, pode
virar "global disfarçado".
Factory Method
Delega a criação de objetos às subclasses.
interface Produto { void usar(); }
class ProdutoA implements Produto { public void usar() {} }
class ProdutoB implements Produto { public void usar() {} }
abstract class Fabrica {
abstract Produto criar();
public void operar() { criar().usar(); }
}
class FabricaA extends Fabrica {
Produto criar() { return new ProdutoA(); }
}
Quando usar: quando não se sabe a classe concreta antecipadamente.
Abstract Factory
Cria famílias de objetos relacionados sem especificar classes concretas. Diferença da
Factory Method: foca em famílias inteiras, não em um produto só.
Builder
Constrói objetos complexos passo a passo.
Pessoa p = new Pessoa.Builder()
.nome("Ana").idade(30).build();
Quando usar: objetos com muitos parâmetros (evita construtores gigantes).
Prototype
Cria novos objetos por clonagem ( clone() ). Quando usar: quando criar do zero é custoso.
3. Padrões Estruturais (Composição de Classes/Objetos)
Adapter
Converte a interface de uma classe em outra esperada pelo cliente.
interface Alvo { void requisicao(); }
class Adaptado { void metodoEspecifico() {} }
class Adapter implements Alvo {
private Adaptado a = new Adaptado();
public void requisicao() { a.metodoEspecifico(); }
}
Quando usar: integrar bibliotecas/legado com interface incompatível.
Decorator
Adiciona responsabilidades dinamicamente a um objeto.
interface Cafe { double custo(); }
class CafeSimples implements Cafe { public double custo() { return 5; } }
class ComLeite implements Cafe {
private Cafe c;
ComLeite(Cafe c) { this.c = c; }
public double custo() { return c.custo() + 2; }
}
Quando usar: estender funcionalidades sem herança (ex.: java.io usa isso).
Facade
Fornece uma interface simplificada para um subsistema complexo. Quando usar: esconder
complexidade de várias classes (ex.: API de alto nível).
Composite
Trata objetos individuais e composições de forma uniforme (árvore). Quando usar: estruturas
hierárquicas (menus, árvore de arquivos).
Proxy
Fornece um substituto/representante de outro objeto (controle de acesso, lazy loading,
cache). Diferença do Decorator: Proxy controla o acesso; Decorator adiciona
comportamento.
Bridge
Separa abstração de implementação para variarem independentemente. Quando usar: evitar
explosão de subclasses.
Flyweight
Compartilha objetos para economizar memória (estado intrínseco vs extrínseco). Quando
usar: muitos objetos similares (ex.: caracteres em editor de texto).
4. Padrões Comportamentais (Comunicação entre Objetos)
Strategy
Define uma família de algoritmos intercambiáveis.
interface Estrategia { int calcular(int a, int b); }
class Soma implements Estrategia { public int calcular(int a, int b){ return a+b; } }
class Multiplica implements Estrategia { public int calcular(int a, int b){ return a*b; } }
class Contexto {
private Estrategia e;
Contexto(Estrategia e) { this.e = e; }
public int executar(int a, int b) { return e.calcular(a, b); }
}
Quando usar: trocar algoritmos em runtime, eliminar if/else gigantes.
Observer
Notifica vários observadores quando um objeto muda.
interface Observer { void atualizar(); }
class Sujeito {
private List obs = new ArrayList();
public void add(Observer o) { obs.add(o); }
public void notificar() { obs.forEach(Observer::atualizar); }
}
Quando usar: eventos, listeners, MVC, sistemas de notificação.
Command
Encapsula uma requisição como objeto (permite desfazer, fila, log).
interface Comando { void executar(); }
class LuzOn implements Comando { public void executar() { /* liga luz */ } }
Quando usar: undo/redo, filas de comandos, macros.
Template Method
Define o esqueleto de um algoritmo, deixando passos para subclasses.
abstract class Jogo {
final void jogar() { iniciar(); executar(); finalizar(); }
abstract void iniciar();
abstract void executar();
abstract void finalizar();
}
Quando usar: quando passos variam mas a ordem é fixa.
Iterator
Percorre coleções sem expor sua estrutura interna. Quando usar: percorrer listas, árvores,
etc. (Java já tem Iterator ).
State
Permite que um objeto mude de comportamento quando seu estado interno muda. Diferença
do Strategy: no State, o objeto muda de estado sozinho; no Strategy, o cliente escolhe.
Chain of Responsibility
Passa uma requisição por uma cadeia de handlers até um tratar. Quando usar: filtros,
validações, logs em pipeline.
Mediator
Centraliza a comunicação entre objetos (mediador), reduzindo acoplamento. Quando usar:
chats, GUIs complexas.
Memento
Captura e restaura o estado de um objeto (undo). Quando usar: histórico de estados.
Visitor
Permite adicionar novas operações a uma estrutura sem alterá-la. Quando usar: quando há
muitas operações sobre classes estáveis.
Interpreter
Define uma gramática e interpreta sentenças. Quando usar: expressões, DSLs simples.
5. Tabela-Resumo (para revisar rápido)
Categoria Padrão Ideia central
Criacional Singleton Instância única
Criacional Factory Method Delega criação
Criacional Abstract Factory Famílias de objetos
Criacional Builder Construção passo a passo
Criacional Prototype Clonagem
Estrutural Adapter Converte interface
Estrutural Decorator Adiciona comportamento
Estrutural Facade Simplifica subsistema
Estrutural Composite Árvore uniforme
Categoria Padrão Ideia central
Estrutural Proxy Representante
Estrutural Bridge Separa abstração/implementação
Estrutural Flyweight Compartilha memória
Comportamental Strategy Algoritmos intercambiáveis
Comportamental Observer Notificação de mudanças
Comportamental Command Requisição como objeto
Comportamental Template Method Esqueleto de algoritmo
Comportamental Iterator Percorrer coleções
Comportamental State Comportamento por estado
Comportamental Chain of Responsibility Cadeia de handlers
Comportamental Mediator Comunicação centralizada
Comportamental Memento Salvar/restaurar estado
Comportamental Visitor Novas operações
Comportamental Interpreter Interpretar gramática
6. Diferenças que caem em prova
Factory Method vs Abstract Factory: um produto vs família de produtos
Adapter vs Decorator: adapta interface vs adiciona comportamento
Proxy vs Decorator: controla acesso vs estende comportamento
Strategy vs State: cliente escolhe vs objeto muda sozinho
Composite vs Decorator: árvore vs embrulho
Facade vs Adapter: simplifica vs converte
7. Boas práticas e princípios SOLID (relação com padrões)
SRP — responsabilidade única
OCP — aberto/fechado (Strategy, Decorator)
LSP — substituição de Liskov
ISP — segregação de interfaces
DIP — inversão de dependência (Factory, Strategy)
Aviso: padrão não é bala de prata — usar só quando faz sentido. Evite overengineering.
8. Pontos-chave para a prova
1. Saber as 3 categorias e dar exemplos de cada
2. Diferenças clássicas (tabela acima)
3. Reconhecer padrãoem diagrama UML ou trecho de código
4. Saber quando usar cada um (ex.: Builder para muitos parâmetros)
5. Relação com SOLID
6. Padrões do Java nativo: java.io (Decorator), Iterator , Observer (Listeners), Singleton
( Runtime.getRuntime() )