Sabe aquele problema que você resolve de um jeito hoje, seu colega resolve de outro jeito amanhã, e daqui a 6 meses ninguém entende nada? Os Design Patterns existem para criar uma linguagem comum de soluções que já funcionam.
O que são GoF Patterns?
Em 1994, quatro engenheiros — Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides — publicaram o livro "Design Patterns: Elements of Reusable Object-Oriented Software". Eles ficaram conhecidos como a Gang of Four (GoF) e catalogaram 23 padrões de projeto divididos em três categorias:
- Criacionais — como os objetos são criados
- Estruturais — como os objetos se organizam
- Comportamentais — como os objetos se comunicam
Neste post vamos ver os mais usados no dia a dia, com exemplos do petshop da Maya, do Pancho e do Romeu.
Padrões Criacionais
Factory Method — "Deixa eu criar isso pra você"
O Factory Method delega a criação de objetos para subclasses, sem expor a lógica de criação para quem usa.
Quando usar: quando você não sabe de antemão qual tipo exato de objeto vai precisar criar, ou quando quer centralizar a lógica de criação em um único lugar.
No petshop: em vez de o sistema saber se está criando um Cachorro ou um Gato em cada lugar, existe uma fábrica que recebe o tipo e entrega o animal certo.
Benefício: adicionar um novo tipo de animal não exige mudar o código de quem usa — só adicionar uma nova opção na fábrica.
Singleton — "Só pode existir um"
O Singleton garante que uma classe tenha apenas uma instância em todo o sistema, com um ponto de acesso global a ela.
Quando usar: para recursos compartilhados que devem ser únicos — conexão com banco de dados, gerenciador de configurações, pool de conexões.
No petshop: o sistema de configurações (URL do banco, porta da aplicação, chave de API) deve existir uma única vez. Criar múltiplas instâncias seria desperdício e fonte de inconsistência.
Cuidado: Singleton é um dos padrões mais abusados. Use com critério — ele cria acoplamento global e dificulta testes. Prefira injeção de dependência quando possível.
Builder — "Construindo passo a passo"
O Builder separa a construção de um objeto complexo da sua representação final, permitindo criar o mesmo tipo de objeto com configurações diferentes.
Quando usar: quando um objeto tem muitos parâmetros opcionais e criar construtores com 10 argumentos viraria um pesadelo.
No petshop: criar um Agendamento pode envolver animal, veterinário, data, serviço, observações, desconto, forma de pagamento. O Builder permite montar esse objeto de forma legível, passo a passo, sem confundir a ordem dos parâmetros.
Padrões Estruturais
Adapter — "Traduzindo interfaces incompatíveis"
O Adapter permite que duas classes com interfaces incompatíveis trabalhem juntas, funcionando como um tradutor entre elas.
Quando usar: quando você precisa integrar uma biblioteca ou serviço externo que tem uma interface diferente do que seu sistema espera.
No petshop: o sistema usa uma interface padrão para enviar notificações. Quando você integra o WhatsApp Business, que tem uma API completamente diferente, o Adapter traduz as chamadas do seu sistema para o formato que a API do WhatsApp entende — sem mudar nada no seu código original.
Decorator — "Adicionando poderes sem herdar"
O Decorator adiciona comportamentos a um objeto em tempo de execução, sem precisar criar subclasses.
Quando usar: quando você precisa adicionar funcionalidades de forma flexível e combinável, sem explodir a hierarquia de herança.
No petshop: um serviço de banho básico custa R$ 50. Adicionar tosa custa mais R$ 30. Adicionar perfume custa mais R$ 15. Com Decorator, você empilha funcionalidades como camadas — cada uma adiciona seu comportamento e seu preço ao serviço base.
Diferença do Builder: o Builder monta um objeto. O Decorator envolve um objeto existente adicionando comportamento.
Padrões Comportamentais
Observer — "Me avisa quando mudar"
O Observer define uma relação de um-para-muitos: quando um objeto muda de estado, todos os seus dependentes são notificados automaticamente.
Quando usar: quando uma ação deve disparar reações em múltiplos lugares sem que o emissor saiba quem são os receptores.
No petshop: quando um agendamento é confirmado, várias coisas precisam acontecer — enviar e-mail para o dono, notificar o veterinário, atualizar o painel administrativo, registrar no histórico. Com Observer, o Agendamento avisa que foi confirmado e cada "observador" reage do seu jeito, de forma independente.
Benefício: adicionar um novo comportamento (ex: enviar SMS) não exige tocar na classe Agendamento — só criar um novo Observer.
Strategy — "Escolhendo o algoritmo em tempo de execução"
O Strategy define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis. O algoritmo pode variar independentemente de quem o usa.
Quando usar: quando você tem várias formas de fazer a mesma coisa e quer poder trocar entre elas sem if/else espalhados pelo código.
No petshop: o sistema aceita múltiplas formas de pagamento — cartão de crédito, Pix, boleto. Cada uma tem sua lógica de processamento completamente diferente. Com Strategy, você passa a estratégia de pagamento escolhida pelo cliente, e o sistema processa sem saber nem se importar com os detalhes.
Chain of Responsibility — "Passa pra frente até alguém resolver"
A Chain of Responsibility passa uma requisição por uma cadeia de handlers. Cada handler decide se processa a requisição ou a passa para o próximo.
Quando usar: quando você tem múltiplos processadores potenciais para uma requisição e quer desacoplar quem envia de quem processa.
No petshop: uma solicitação de desconto chega ao sistema. Primeiro passa pelo atendente (pode dar até 5%). Se precisar de mais, passa para o gerente (até 15%). Se precisar de mais ainda, vai para o dono (acima de 15%). Cada handler trata o que pode ou passa adiante.
Resumo dos padrões do dia a dia
| Padrão | Categoria | Em uma frase |
|---|---|---|
| Factory Method | Criacional | Centraliza a criação de objetos |
| Singleton | Criacional | Garante uma única instância |
| Builder | Criacional | Constrói objetos complexos passo a passo |
| Adapter | Estrutural | Traduz interfaces incompatíveis |
| Decorator | Estrutural | Adiciona comportamento sem herança |
| Observer | Comportamental | Notifica múltiplos dependentes automaticamente |
| Strategy | Comportamental | Troca algoritmos em tempo de execução |
| Chain of Responsibility | Comportamental | Passa a requisição até alguém resolver |
O erro mais comum com Design Patterns
Forçar padrões onde não cabem.
Design Patterns são soluções para problemas conhecidos — não decoração de código. Se você está aplicando um padrão e o código ficou mais difícil de entender, provavelmente o problema não pedia aquele padrão.
A pergunta certa não é "qual padrão posso usar aqui?", mas sim "qual problema estou tentando resolver?"