Pular para o conteúdo principal

Facade

Descrição​

O Facade oferece uma interface única e simplificada para um conjunto de interfaces de um subsistema. Em vez de o cliente conhecer e coordenar várias classes internas, ele conversa com um único objeto de fachada que expõe operações de alto nível.

A fachada sabe quais classes do subsistema são responsáveis por cada pedido e delega o trabalho a elas, na ordem correta. As classes do subsistema continuam funcionando de forma independente e não conhecem a fachada; clientes avançados ainda podem acessá-las diretamente quando precisarem de mais controle.

O resultado é uma camada que reduz o acoplamento entre clientes e detalhes de implementação, facilitando o uso, a manutenção e a evolução do subsistema.

Problemas que resolve​

  • Clientes precisam orquestrar muitas classes de baixo nível (bibliotecas, frameworks, APIs legadas) para executar uma tarefa simples.
  • Mudanças internas em um subsistema se propagam para todo o código que o utiliza.
  • Dependências complexas entre camadas dificultam entender o ponto de entrada de um módulo.
  • Código de integração repetido em vários lugares para realizar a mesma sequência de chamadas.

Quando usar​

  • Quando se quer fornecer uma interface simples para um subsistema complexo.
  • Para estruturar um sistema em camadas, definindo um ponto de entrada para cada uma.
  • Para isolar o código cliente de bibliotecas de terceiros ou sistemas legados, facilitando substituí-los.
  • Quando há muitas dependências entre clientes e classes de implementação e se deseja desacoplá-los.

Quando evitar​

  • Quando o subsistema já é simples; a fachada só adicionaria uma camada desnecessária.
  • Quando os clientes precisam de todo o poder e flexibilidade do subsistema e a fachada acabaria replicando toda a sua API.
  • Quando a fachada tende a virar um "god object", acumulando responsabilidades não relacionadas.

Trade-offs​

GanhoCusto / Risco
Interface simples e fácil de usarPode esconder funcionalidades úteis ou limitar casos avançados
Menor acoplamento entre clientes e subsistemaMais uma camada de indireção para manter
Mudanças internas ficam isoladas atrás da fachadaRisco de a fachada crescer demais e virar um "god object"
Ponto de entrada claro para camadas e módulosPode mascarar problemas de design no subsistema em vez de resolvê-los
  • Acoplamento: o cliente depende apenas da fachada, mas a fachada fica acoplada a várias classes do subsistema.
  • Testabilidade: clientes ficam fáceis de testar com um dublê da fachada; a própria fachada exige testes de integração ou mocks dos componentes.
  • Complexidade: baixa; o padrão não exige herança nem interfaces especiais.
  • Desempenho: impacto desprezível, apenas uma chamada a mais de delegação.

Diagrama​

O Client interage apenas com a Facade, que delega as chamadas para SubsystemA, SubsystemB e SubsystemC na ordem adequada. As classes do subsistema não conhecem a fachada.

Exemplo​

Um e-commerce precisa finalizar pedidos verificando estoque, cobrando o pagamento e agendando a entrega. Em vez de cada controlador coordenar esses três serviços, um OrderFacade expõe uma única operação placeOrder.

class InventoryService {
reserve(sku: string, qty: number): void { /* ... */ }
}

class PaymentService {
charge(customerId: string, amount: number): string { return "tx-123"; }
}

class ShippingService {
schedule(customerId: string, sku: string): string { return "track-456"; }
}

class OrderFacade {
constructor(
private inventory = new InventoryService(),
private payment = new PaymentService(),
private shipping = new ShippingService(),
) {}

placeOrder(customerId: string, sku: string, qty: number, amount: number): string {
this.inventory.reserve(sku, qty);
this.payment.charge(customerId, amount);
return this.shipping.schedule(customerId, sku);
}
}

// Cliente
const tracking = new OrderFacade().placeOrder("c-1", "SKU-9", 2, 199.9);

Padrões relacionados​

  • Adapter — o Adapter converte uma interface existente para outra esperada; o Facade cria uma interface nova e mais simples para um conjunto de classes.
  • Mediator — ambos centralizam a comunicação, mas o Mediator coordena colegas que o conhecem, enquanto o Facade é transparente para o subsistema.
  • Abstract Factory — pode ser usado junto com o Facade para criar os objetos do subsistema de forma independente de plataforma.
  • Singleton — frequentemente basta uma única instância da fachada.
  • Proxy — também se interpõe entre cliente e objeto real, mas mantém a mesma interface em vez de simplificá-la.

Referência​