Padrões Estruturais
Intenção da categoria
Seção intitulada “Intenção da categoria”Enquanto os criacionais lidam com o nascimento dos objetos e os comportamentais com sua conversa, os estruturais lidam com a montagem: como conectar interfaces incompatíveis, envelopar objetos para adicionar responsabilidades, ou organizar hierarquias. A maioria favorece composição sobre herança, um dos princípios fundacionais do catálogo.
Os sete padrões
Seção intitulada “Os sete padrões”Adapter
Seção intitulada “Adapter”Intenção: converte a interface de uma classe na interface que o cliente espera, permitindo que classes com interfaces incompatíveis trabalhem juntas. Existe em duas formas: adapter de classe (por herança múltipla, limitado em Java) e adapter de objeto (por composição, o mais usado).
Quando usar: integrar uma biblioteca de terceiros ou código legado cuja interface não bate com a esperada pelo seu domínio.
Intenção: desacopla uma abstração de sua implementação para que as duas variem independentemente. Em vez de uma hierarquia combinatória (FormaVermelhaCirculo, FormaAzulQuadrado…), separa “Forma” de “Renderizador” e as compõe.
Quando usar: quando você tem duas dimensões ortogonais de variação que, por herança, gerariam uma explosão de subclasses.
Composite
Seção intitulada “Composite”Intenção: compõe objetos em estruturas de árvore para representar hierarquias parte-todo, permitindo que o cliente trate objetos individuais (folhas) e composições (nós) de forma uniforme.
Quando usar: hierarquias recursivas — árvore de arquivos, componentes de UI, expressões, itens de menu.
Decorator — ver Decorator
Seção intitulada “Decorator — ver Decorator”Intenção: adiciona responsabilidades a um objeto dinamicamente, envelopando-o em outro objeto que implementa a mesma interface. Alternativa flexível à herança para estender comportamento.
Quando usar: quando você quer combinar responsabilidades opcionais em tempo de execução (o clássico BufferedInputStream(new FileInputStream(...)) do java.io).
Facade — ver Facade
Seção intitulada “Facade — ver Facade”Intenção: fornece uma interface unificada e de mais alto nível para um conjunto de interfaces de um subsistema, tornando-o mais fácil de usar.
Quando usar: reduzir a superfície de acoplamento entre clientes e um subsistema complexo. Detalhes e contraste com Ports na nota Facade.
Flyweight
Seção intitulada “Flyweight”Intenção: usa compartilhamento para suportar eficientemente um grande número de objetos de granularidade fina, separando estado intrínseco (compartilhável, imutável) de extrínseco (passado pelo cliente).
Quando usar: milhões de objetos quase iguais (glifos em um editor, partículas, tiles de um mapa) onde a memória é o gargalo.
Proxy — ver Proxy
Seção intitulada “Proxy — ver Proxy”Intenção: fornece um substituto ou representante de outro objeto para controlar o acesso a ele.
Quando usar: adicionar controle de acesso, lazy loading, cache ou representação remota sem mudar o objeto real. Tipos (virtual, remoto, proteção) e comparação com Decorator na nota Proxy.
IMPORTANTE: Adapter do GoF vs. adapter da Arquitetura Hexagonal
Seção intitulada “IMPORTANTE: Adapter do GoF vs. adapter da Arquitetura Hexagonal”Os dois conceitos compartilham a ideia de tradução entre interfaces, mas não são idênticos — e confundi-los gera bugs de vocabulário em discussões de design.
| Aspecto | Adapter (GoF) | Adapter Hexagonal (Adapters) |
|---|---|---|
| Escopo | Micro-padrão de design OO: uma classe traduz a interface de outra | Elemento arquitetural: liga a aplicação ao mundo externo através de um Port |
| Motivação | Reaproveitar uma classe com interface incompatível | Isolar o núcleo de tecnologia (DB, HTTP, fila) — regra de dependência |
| Direção | Cliente → interface esperada → objeto adaptado | Driving (entrada) ou driven (saída), sempre implementando/consumindo um Port |
| Granularidade | Uma classe | Um conjunto de classes de infraestrutura |
Em outras palavras: todo adapter hexagonal frequentemente usa o padrão Adapter do GoF por dentro (traduzindo, digamos, uma entidade de domínio para um DTO de um driver JDBC), mas o conceito arquitetural é maior — ele existe para satisfazer a regra de dependência da Arquitetura Hexagonal, não apenas para casar duas assinaturas de método. Um é tática; o outro é estratégia. Ver Adapters e Ports.
Diagrama — Adapter (objeto)
Seção intitulada “Diagrama — Adapter (objeto)”classDiagram
class Cliente
class Alvo {
<<interface>>
+requisicao()
}
class Adaptado {
+requisicaoEspecifica()
}
class Adapter {
-adaptado : Adaptado
+requisicao()
}
Cliente --> Alvo : depende
Alvo <|.. Adapter
Adapter --> Adaptado : delega
Anti-padrões e erros comuns
Seção intitulada “Anti-padrões e erros comuns”- Confundir Decorator com Proxy: ambos envelopam e mantêm a mesma interface, mas a intenção difere — Decorator acrescenta comportamento; Proxy controla acesso. Ver Proxy.
- Facade que vira God Object: uma fachada que acumula lógica de negócio em vez de apenas delegar/coordenar deixa de simplificar e vira um monólito.
- Composite forçando operações sem sentido na folha: expor
adicionar(filho)na interface comum obriga folhas a lançarem exceção, tensionando o LSP. - Chamar “adapter hexagonal” de “Adapter do GoF” (e vice-versa): como acima, são conceitos de escopos diferentes; misturá-los confunde discussões arquiteturais.
Relações
Seção intitulada “Relações”- Notas próprias da categoria: Proxy, Facade.
- Categoria irmã: Padrões Criacionais, Padrões Comportamentais.
- Índice: Design Patterns (GoF).
- Arquitetura: Arquitetura Hexagonal, Ports, Adapters.
- Princípios: LSP - Liskov Substitution Principle, OCP - Open-Closed Principle.
Perguntas de revisão
Seção intitulada “Perguntas de revisão”1. Qual é o foco dos padrões estruturais, em contraste com criacionais e comportamentais?
Resposta
A composição de classes e objetos em estruturas maiores — o encaixe entre partes. Criacionais focam na instanciação; comportamentais, na distribuição de responsabilidade e no fluxo de controle.
2. Como o Adapter do GoF difere do adapter da Arquitetura Hexagonal?
Resposta
O Adapter do GoF é um micro-padrão OO: uma classe traduz a interface de outra. O adapter hexagonal é um elemento arquitetural que liga o núcleo ao exterior implementando/consumindo um Port para satisfazer a regra de dependência. O hexagonal costuma usar o padrão GoF por dentro, mas seu propósito é estratégico, não apenas casar assinaturas.
3. Decorator e Proxy têm a mesma forma; o que os distingue?
Resposta
A intenção. Decorator envelopa para adicionar responsabilidades/comportamento; Proxy envelopa para controlar o acesso ao objeto real (lazy, cache, proteção, remoto). A estrutura é quase idêntica; a diferença está no propósito.
4. Quando o Bridge evita uma explosão de subclasses?
Resposta
Quando há duas dimensões ortogonais de variação (ex: tipo de forma × tipo de renderização). Herança combinaria as duas em N×M subclasses; o Bridge separa abstração de implementação e as compõe, resultando em N+M classes.