Pular para o conteúdo
GoF/23 Padrões de Projeto Estruturais
185
Estrutural escopo de objeto

Facade

Fachada

Uma porta de entrada simples para um subsistema complicado.

Complexidade simples Frequência de uso muito comum
D

Definição

Intenção — palavra por palavra, como o livro define

Fornecer uma interface unificada para um conjunto de interfaces de um subsistema. Facade define uma interface de nível mais alto que torna o subsistema mais fácil de usar.

E

Exemplo e motivação

Analogia

O atendente da central

Para pedir uma pizza você liga e fala uma frase. Do outro lado, há um sistema de pedidos, um controle de estoque, uma cozinha, um roteirizador de entrega e um gateway de pagamento. O atendente é a fachada: ele conhece todo mundo e coordena, e você só precisa saber uma coisa — o número do telefone.

O problema

Usar um subsistema exige inicializar dezenas de objetos na ordem certa, conhecer detalhes de implementação e conectar tudo. Essa “cola” acaba espalhada pela aplicação, acoplando sua lógica de negócio a um subsistema que pode mudar.

A solução

Crie uma classe com um punhado de métodos de alto nível, expressos na linguagem do seu domínio, que fazem essa coordenação por dentro. O cliente conversa só com ela.

Sintomascomo reconhecer no seu código
  • A mesma sequência de 8 chamadas repetida em vários controllers.
  • Imports de dezenas de classes internas de uma lib no seu domínio.
Na práticaonde ele já existe
  • javax.faces.context.FacesContext
  • jQuery — uma fachada sobre a API do DOM
  • SDKs oficiais de serviços em nuvem (AWS SDK, Stripe SDK)
D

Diagrama

ClientConversorDeVideo+ converter(arq, fmt)LeitorDeArquivoCodecMixerDeAudio1 chamada
Fig. 10 — Facade herda / implementa cria usa / contém
Ver este diagrama sendo desenhado, traço a traço
Participantes
Facade
Sabe a quem delegar cada pedido e coordena o subsistema.
Additional Facade
(opcional) Segunda fachada para evitar que a primeira vire um monstro.
Subsystem classes
Fazem o trabalho real; não conhecem a fachada.
Client
Usa a fachada em vez de dezenas de classes.
A

Aplicabilidade

Use quando
  • Você quer uma interface simples para um subsistema complexo.
  • Você quer organizar um subsistema em camadas — cada camada expõe sua fachada.
  • Você quer reduzir a dependência entre o cliente e muitas classes internas.
Evite quando
  • O subsistema já é simples — a fachada vira indireção vazia.
C

Consequências

A favor
  • Isola o código do cliente da complexidade do subsistema.
  • Reduz o acoplamento: se o subsistema mudar, só a fachada muda.
  • Dá um vocabulário de alto nível, na linguagem do domínio.
Contra
  • A fachada pode virar um objeto-deus acoplado a tudo no sistema.
  • Pode esconder capacidades legítimas do subsistema — deixe o acesso direto disponível para casos avançados.
Apêndice

Código

Listagem 10 Uma chamada esconde seis passos de um checkout
// ── O subsistema: classes reais, complexas, independentes ──
class Estoque      { reservar(itens)      { return { reservaId: 'r_77', itens }; } }
class Precificador { calcular(itens, cupom) { const t = itens.length * 100; return cupom ? t * 0.9 : t; } }
class Pagamentos   { cobrar(valor, cartao) { return { pago: true, tx: 'tx_42', valor }; } }
class Fiscal       { emitirNota(pedido)    { return { nfe: '35240...', pedido: pedido.id }; } }
class Logistica    { agendar(endereco)     { return { rastreio: 'BR123', prazo: '3 dias' }; } }
class Emails       { enviarConfirmacao(email, pedido) { return `✉️ enviado para ${email}`; } }

// ── A FACHADA: um método, na linguagem do negócio ─────
class CheckoutFacade {
  constructor() {
    this.estoque     = new Estoque();
    this.preco       = new Precificador();
    this.pagamentos  = new Pagamentos();
    this.fiscal      = new Fiscal();
    this.logistica   = new Logistica();
    this.emails      = new Emails();
  }

  // Toda a ordem, a coordenação e o tratamento de erro moram AQUI.
  finalizarCompra({ itens, cupom, cartao, endereco, email }) {
    const reserva = this.estoque.reservar(itens);
    const total   = this.preco.calcular(itens, cupom);
    const cobranca = this.pagamentos.cobrar(total, cartao);
    if (!cobranca.pago) throw new Error('pagamento recusado');

    const pedido  = { id: 'p_900', reserva: reserva.reservaId, total, tx: cobranca.tx };
    const nota    = this.fiscal.emitirNota(pedido);
    const entrega = this.logistica.agendar(endereco);
    this.emails.enviarConfirmacao(email, pedido);

    return { pedido: pedido.id, total, nfe: nota.nfe, rastreio: entrega.rastreio };
  }
}

// ── O cliente: 1 linha, zero conhecimento do subsistema ─
const checkout = new CheckoutFacade();
console.log(checkout.finalizarCompra({
  itens: ['sku-1', 'sku-2'], cupom: 'BEMVINDO', cartao: '4111…',
  endereco: 'Rua A, 100', email: 'ana@x.com',
}));
// { pedido: 'p_900', total: 180, nfe: '35240...', rastreio: 'BR123' }
Apêndice

Relações

parecido / fácil de confundir
Adapter
Adapter adapta UM objeto a uma interface existente; Facade cria uma interface NOVA sobre VÁRIOS objetos.
Mediator
Facade define interface UNIDIRECIONAL e os subsistemas a ignoram; Mediator centraliza comunicação BIDIRECIONAL e os colegas o conhecem.
Proxy
Proxy tem a mesma interface do alvo; Facade tem uma interface própria e mais simples.
costuma andar junto
Singleton
Uma fachada sem estado geralmente pode ser única.
alternativa a
Abstract Factory
Abstract Factory pode ser uma alternativa quando o que se quer esconder é só a criação.
Apêndice

Verificação

Questãoa resposta está marcada

Qual é a diferença central entre Facade e Mediator?

  1. Na Facade os subsistemas não a conhecem e o fluxo é unidirecional; no Mediator os colegas o conhecem e a comunicação é bidirecional
  2. Facade só pode envolver uma classe
  3. Mediator é um padrão estrutural e Facade é comportamental
  4. Facade não pode ser usada com Singleton

Facade simplifica o acesso a um subsistema que a ignora completamente. Mediator existe para que colegas que se conhecem parem de falar entre si e falem com ele.