Design de software

Diferenças entre Adapter, Facade, Proxy e Decorator

Adapters transformam interfaces, facades ocultam complexidade, proxies controlam o acesso e decorators adicionam funcionalidades. Compare quatro padrões de encapsulamento estruturalmente parecidos por intenção e critérios de escolha.

5 min de leitura
Imagem de capa de Diferenças entre Adapter, Facade, Proxy e Decorator

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.

Basta perguntar por que algo está sendo encapsulado para a diferença aparecer
Basta perguntar por que algo está sendo encapsulado para a diferença aparecer

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.

Quando ficava em dúvida, eu deixava este lembrete colado no monitor
Quando ficava em dúvida, eu deixava este lembrete colado no monitor

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.

Leia também