Os quatro irmãos dos padrões de encapsulamento: por que são tão confusos?
Ao estudar padrões de projeto, sempre chega um ponto em que você bate em uma parede.
Adapter, Facade, Proxy e Decorator. É fácil misturar os quatro e se confundir.
É natural pensar: “Eles não fazem todos apenas encapsular outro objeto?”. De fato, os quatro mantêm outro objeto dentro e ficam à frente dele, então parecem iguais por fora.
Por isso, muita gente memoriza os nomes, mas ainda não consegue diferenciá-los no código.
Vamos direto ao ponto.
Os quatro padrões encapsulam objetos, mas fazem isso com “objetivos” diferentes.
O Adapter muda a interface, o Facade oculta a complexidade, o Proxy controla o acesso e o Decorator adiciona funcionalidades.
Tendo essa frase em mente, o restante fica fácil. Neste artigo, vamos separar claramente os quatro irmãos para que você saiba qual é qual no código.
Se precisar de uma implementação real depois da comparação, continue com Encapsulando uma API legada com Adapter em Swift e Simplificando um subsistema com Facade em Swift.
Tabela comparativa dos quatro irmãos
Antes de explicar em texto, vamos olhar uma tabela. Eu deixava esta tabela na frente da mesa e consultava sempre que ficava em dúvida.
| Padrão | Objetivo | Interface | Alvo encapsulado |
|---|---|---|---|
| Adapter | Adapta uma interface incompatível | Muda | Geralmente um |
| Facade | Oferece uma entrada simples para vários subsistemas complexos | Cria uma nova | Vários |
| Proxy | Controla, adia ou armazena em cache o acesso ao original | Igual | Um |
| Decorator | Adiciona funcionalidades ao original | Igual | Um |
O critério mais importante é: “a interface permanece igual?”
Proxy e Decorator têm a mesma interface do original, então quem usa não precisa saber que existe um objeto encapsulado.
Já o Adapter muda a interface de propósito, enquanto o Facade cria uma entrada completamente nova.
Adapter vs. Decorator: qual é a diferença?
Esta é a dupla que mais causa confusão. No código, a diferença fica evidente.
Adapter é um conversor que faz o incompatível funcionar junto. Sim, como o adaptador que conecta um dispositivo de 220 V a uma tomada de 110 V.
// A biblioteca existente só tem legacyPrint(text:)
// Quando nosso código espera draw()
protocol Renderer { func draw() }
struct LegacyLabel { func legacyPrint(_ t: String) { print(t) } }
struct LabelAdapter: Renderer {
let legacy: LegacyLabel
func draw() { legacy.legacyPrint("Chamada convertida") }
}
LabelAdapter(legacy: LegacyLabel()).draw()
// Saída: chamada convertida
O ponto central é que a interface muda de legacyPrint para draw.
Decorator mantém a interface e apenas adiciona funcionalidades, como colocar uma dose extra de café.
protocol Coffee { func cost() -> Int }
struct Americano: Coffee { func cost() -> Int { 4000 } }
struct ShotDecorator: Coffee {
let base: Coffee
func cost() -> Int { base.cost() + 500 }
}
ShotDecorator(base: Americano()).cost()
// Saída: 4500
Os dois contêm um base, mas o Adapter muda nomes e o Decorator amplia o comportamento. Os objetivos são completamente diferentes.
E Proxy vs. Facade?
O Proxy tem exatamente a mesma interface do original, mas faz o controle no meio do caminho.
No carregamento de imagens, ele não carrega a imagem real imediatamente; espera até que ela seja necessária. Isso é lazy loading.
Cache, verificação de permissões e logging também são tarefas comuns do Proxy. Quem usa acha que está chamando o original, mas na verdade chama um representante.
O Facade é um pouco diferente. Ele não encapsula uma coisa só; esconde várias atrás de si.
Em um home theater, ele reúne ligar o projetor, ligar as caixas de som, diminuir as luzes e iniciar a reprodução em uma única chamada watchMovie(). Assim, um botão basta sem conhecer os detalhes internos.
Em resumo, Proxy é “o porteiro da mesma porta”, enquanto Facade é “o balcão de atendimento que abre várias portas por você”.
Quando usar e quando evitar
Padrões são ferramentas, então use-os conforme a situação. Forçar um padrão só deixa o código mais complexo.
| Situação | Escolha |
|---|---|
| A interface de uma biblioteca externa não é compatível | Adapter |
| Você quer uma entrada simples para vários módulos complexos | Facade |
| É necessário controle de acesso, lazy loading ou cache | Proxy |
| Você quer combinar e adicionar funcionalidades com flexibilidade | Decorator |
Também existem situações claras em que é melhor evitá-los.
- Se não há motivo para encapsular algo, adicionar um padrão só para dizer que o usou apenas aumenta as camadas.
- Se você empilhar decorators demais, depurar vira um inferno: fica impossível rastrear onde um valor mudou.
- Se o Facade assumir responsabilidades demais, ele próprio vira um bloco gigante.
Eu me pergunto: “Qual dos quatro objetivos justifica este encapsulamento?”. Se não encontro uma resposta, removo o padrão.
É assim que perguntam em entrevistas
P. Proxy e Decorator encapsulam objetos com a mesma interface. Qual é a diferença?
R. Os objetivos são diferentes. O Proxy controla, adia ou armazena em cache o acesso ao original, mantendo sua funcionalidade intacta. O Decorator mantém a interface original e adiciona funcionalidades. Pense assim: o Proxy decide “se deve chamar”, enquanto o Decorator decide “o que fazer depois da chamada”.
P. Qual é a diferença entre Adapter e Facade?
R. O Adapter normalmente encapsula um único alvo para adaptar uma interface incompatível. O Facade encapsula vários subsistemas e oferece uma nova entrada simples. O Adapter “traduz” a interface; o Facade a “resume”.
Conclusão
A diferença entre os quatro irmãos se resume a uma pergunta: “Por que você está encapsulando?”. Para mudar, ocultar, controlar ou adicionar algo à interface?
Com essa pergunta, você não ficará mais confuso diante do código. Salve a tabela comparativa de hoje e consulte-a quando precisar.

