Design Patterns: Facade (Parte 6)
Contexto
Na Parte 5 falamos de State. Agora voltamos a um padrão estrutural que aparece muito em código de aplicação: Facade. A dor que ele resolve é mais “humana” do que acadêmica: quando um subsistema cresce, consumir esse subsistema passa a exigir que você saiba demais (ordem das chamadas, detalhes, dependências indiretas). O Facade cria um ponto de entrada mais simples.
A intenção é esconder a complexidade de um subsistema atrás de uma interface amigável. Isso não elimina a complexidade; ele só organiza o acesso. Em vez de dez classes e vinte métodos “espalhados” pela base chamando serviços em ordens diferentes, você concentra um fluxo típico num lugar só, com um nome que faz sentido para quem lê.
É útil também não confundir com Adapter. Adapter existe para compatibilizar interfaces incompatíveis. Facade existe para reduzir o número de pontos de contato com um subsistema e oferecer uma API mais simples para consumo.
Exemplo na prática
Imagine um fluxo de checkout que, internamente, fala com estoque, pagamento e notificação:
<?php
final readonly class InventoryService
{
public function reserve(string $sku, int $qty): void
{
// ...
}
}
final readonly class PaymentGateway
{
public function charge(int $amountCents, string $token): string
{
// ...
return 'ch_123';
}
}
final readonly class Mailer
{
public function sendReceipt(string $email, string $chargeId): void
{
// ...
}
}
final readonly class CheckoutFacade
{
public function __construct(
private InventoryService $inventory,
private PaymentGateway $payments,
private Mailer $mailer,
) {}
public function placeOrder(string $sku, int $qty, int $amountCents, string $token, string $email): string
{
$this->inventory->reserve($sku, $qty);
$chargeId = $this->payments->charge($amountCents, $token);
$this->mailer->sendReceipt($email, $chargeId);
return $chargeId;
}
}
Repare no papel do CheckoutFacade: ele não tenta “virar o sistema todo”. Ele só dá um caminho de uso comum com um nome claro (placeOrder) e orquestra a sequência. Cada serviço (InventoryService, PaymentGateway, Mailer) continua coeso no próprio papel, enquanto o restante da aplicação para de depender da ordem exata e dos detalhes dessas chamadas. Em sistemas reais, você ainda vai pensar em transação, compensação, idempotência e afins (saga/outbox etc.), mas a ideia do Facade permanece: reduzir atrito de consumo.
O risco do Facade “gordo”
O cuidado aqui é o Facade virar um God Object: o lugar onde tudo acontece e onde regras de negócio de tudo se acumulam. Um bom Facade costuma ser “fino”: ele coordena, mas não tenta absorver responsabilidade que pertence ao domínio ou aos serviços especializados. Se o Facade começa a ter decisões complexas e regras centrais, pode ser sinal de que você está misturando orquestração com modelagem.
Conclusão
Facade melhora ergonomia e reduz barreira cognitiva para consumir subsistemas. Use quando muitas classes precisam ser usadas juntas de forma repetida.
Referências
- Design Patterns (GoF).