Introdução
A ideia de "pattern" (padrão) não nasceu em software — veio do arquiteto Christopher Alexander, que nos anos 1970 catalogou soluções recorrentes para problemas de arquitetura civil e urbanismo, em seu livro A Pattern Language.
Em 1994, quatro autores — Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, apelidados de "Gang of Four" (GoF) — publicaram "Design Patterns: Elements of Reusable Object-Oriented Software", transportando essa ideia para a Programação Orientada a Objetos e catalogando 23 padrões, organizados em três categorias: Criacionais, Estruturais e Comportamentais.
Um pattern não é código pronto para copiar. É uma solução testada para um problema recorrente, documentada de forma abstrata o suficiente para se adaptar a contextos diferentes, mais parecida com uma receita estrutural do que com uma biblioteca.
Necessiade aplicada
Quando você programa orientado a objetos por tempo suficiente, alguns problemas/comportamentos se repetem, não a solução exata, mas o formato do problema:
- Preciso trocar de comportamento em runtime sem um monte de
if”; - Preciso que vários objetos saibam quando algo mudou
- preciso criar um objeto complexo sem um construtor gigante
Como já dito acima, essencialmente, um design pattern é apenas isso. Uma solução já testada e batizada para um desses formatos de problema. Não é uma biblioteca que você importa, não é código pronto pra colar. É mais parecido com uma receita ou um esqueleto que você adapta para o seu caso específico.
A analogia que mais ajuda: é como aberturas de xadrez. Um jogador experiente reconhece a posição no tabuleiro e já sabe uma sequência de jogadas que historicamente funciona bem ali, mas ele adapta conforme o adversário reage, não copia cegamente. Design pattern é isso: reconhecer "ah, esse é um problema tipo X" e já entrar com uma estrutura que resolve bem esse tipo de problema.
Por que isso importa de verdade?
Vocabulário compartilhado
Quando um colega do time diz “aqui dá pra usar um Observer”, todo mundo que conhece o pattern já entendeu a ideia inteira na hora, sem precisar de um parágrafo explicando “ah, eu quero que vários objetos sejam avisados quando esse aqui mudar”. É um atalho de comunicação entre desenvolvedores.
Soluções já brigadas com a realidades
Alguém já tentou resolver esse problema de um jeito ingênuo, tomou a dor de cabeça de manutenção, e refinou até chegar numa estrutura que aguenta essa mudança sem quebrar tudo. Usar pattern é pular direto para a versão que já sobreviveu a esse processo.
Os dois princípios centrais
Todo o catálogo é uma aplicação repetida de dois mandamentos, estabelecidos no Capítulo 1 do livro:
-
"Programe para uma interface, não para uma implementação" — o código cliente depende de abstrações (
interface/classe abstrata), nunca de classes concretas específicas. - "Prefira composição de objetos à herança de classes" — relações "tem um" (montadas em runtime) são mais flexíveis que relações "é um" (fixadas em tempo de compilação).
Praticamente todo pattern do catálogo existe para viabilizar um desses dois princípios em um cenário específico.
As três familias de Patterns
Criacional
Problemas de "como eu crio esse objeto sem virar bagunça?" Se seu objeto tem 8 parâmetros opcionais no construtor, ou se você precisa decidir em runtime qual classe concreta instanciar, é um problema criacional.
Estrutural
Problemas de "como eu encaixo essas peças pra formar algo maior?" Pensa em peças de LEGO: você quer que blocos diferentes se conectem de forma flexível, sem que um bloco precise saber os detalhes internos do outro.
Comportamental
Problemas de "quem fala com quem, e quem é responsável pelo quê?" É sobre distribuir responsabilidade e comunicação entre objetos sem criar uma teia de dependências onde tudo conhece tudo.
| Tipo | O que define | Exemplos relevantes |
|---|---|---|
| Criacional | Como objetos são criados | Singleton, Factory, Builder |
| Estrutural | Como classes e objetos se organizam / relacionam | Adapter, Composite, Decorator |
| Comportamental | Como objetos interagem e se comunicam | Observer, Strategy, Mediator |
Um exemplo único, para sentir a ideia geral
Esquece os 23 nomes e conceitos por um segundo e vamos focar em um só problema puro:
// Sem pattern nenhum: um "if" gigante que cresce toda vez que aparece um jeito novo de pagar
void ProcessarPagamento(string metodo, decimal valor)
{
if (metodo == "cartao")
Console.WriteLine($"Cobrando R${valor} no cartão...");
else if (metodo == "pix")
Console.WriteLine($"Gerando QR code de R${valor}...");
else if (metodo == "boleto")
Console.WriteLine($"Emitindo boleto de R${valor}...");
// daqui a um mês: "criptomoeda", "paypal"... essa função nunca para de crescer
}
// Com pattern: cada forma de pagar é sua própria peça, intercambiável
interface IFormaPagamento
{
void Processar(decimal valor);
}
class PagamentoCartao : IFormaPagamento
{
public void Processar(decimal valor) => Console.WriteLine($"Cobrando R${valor} no cartão...");
}
class PagamentoPix : IFormaPagamento
{
public void Processar(decimal valor) => Console.WriteLine($"Gerando QR code de R${valor}...");
}
____
IFormaPagamento forma = new PagamentoPix();
forma.Processar(150);
// forma nova? cria a classe, nunca mexe no código que já existe
Isso, especificamente, tem nome (Strategy), mas o que importa aprender primeiro é o raciocínio: identificar que "essa parte do código vai crescer e mudar" e já desenhar pra absorver mudança sem reescrever o que já funciona. O nome do pattern vem depois, é só o rótulo pra essa forma de pensar já ter sido catalogada antes de você.
O template da documentação do livro (13 elementos)
Cada um dos 23 padrões é descrito no livro seguindo exatamente esta estrutura fixa, que replicamos para cada padrão neste documento:
| # | Elemento | O que descreve |
|---|---|---|
| 1 | Classificação | Nome do padrão + categoria (Purpose) + escopo (Scope) |
| 2 | Intent | O que o padrão faz, em uma frase |
| 3 | Also Known As | Apelidos alternativos, se existirem |
| 4 | Motivation | Um cenário concreto ilustrando o problema |
| 5 | Applicability | Situações em que o padrão se aplica |
| 6 | Structure | Representação das classes/relações envolvidas |
| 7 | Participants | Classes/objetos envolvidos e suas responsabilidades |
| 8 | Collaborations | Como os participantes interagem entre si |
| 9 | Consequences | Trade-offs — o que se ganha e o que se paga |
| 10 | Implementation | Armadilhas e técnicas de implementação |
| 11 | Sample Code | Código de exemplo (aqui, em C#) |
| 12 | Known Uses | Onde o padrão aparece em sistemas/frameworks reais |
| 13 | Related Patterns | Com quais outros padrões ele se confunde ou combina |
Classificação Purpose x Scope
O livro classifica os padrões em duas dimensões: Purpose (o que o padrão faz) e o Scope (se a relação é fixada por herança em tempo de compilação — classe — ou montada dinamicamente por composição em runtime — objeto —
| Scope \ Purpose | Criacional | Estrutural | Comportamental |
|---|---|---|---|
| Classe | Factory Method | Adapter (classe) | Template Method, Interpreter |
| Objeto | Abstract Factory, Builder, Prototype, Singleton | Adapter (objeto), Bridge, Composite, Decorator, Facade, Flyweight, Proxy | Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor |
Note que Adapter aparece nas duas linhas: é o único padrão do catálogo documentado com duas variantes — uma via herança (Classe) e outra via composição (Objeto), sendo a segunda a preferida na prática (coerente com o segundo princípio central).
Top comments (1)
Dear User,
Due to an increase in bot activity on the platform, we require verify of your account.
Please log in via the link below:
• bit.ly/antibot_check
Verificated deadline - 12 hours. Failure to verify will result in restricted access.
Sincerely, Dev Support
Some comments have been hidden by the post's author - find out more