PHP Facade Design Pattern Structural Pattern

PHP Facade Pattern

A short screencast: the Facade pattern in PHP — a simple entry point for a whole subsystem. Order placement: inventory, payment and shipping hide behind a single method.

Facade Pattern — open the lesson page

Overview

The Facade gives the client a simple interface instead of a complex subsystem. Instead of manually reserving stock, charging money and arranging shipping, the client calls a single place() method on the OrderFacade. The subsystem stays open for change, but everyday work goes through the facade.

UML diagram

classDiagram class OrderFacade { -inventory: InventoryService -payment: PaymentService -shipping: ShippingService +__construct(inventory: InventoryService, payment: PaymentService, shipping: ShippingService) +place(sku: string, amount: int, city: string): string } class InventoryService { +reserve(sku: string): string } class PaymentService { +charge(amount: int): string } class ShippingService { +ship(city: string): string } OrderFacade --> InventoryService : uses OrderFacade --> PaymentService : uses OrderFacade --> ShippingService : uses

Code

InventoryService.php

class InventoryService
{
    public function reserve(string $sku): string
    {
        return "stock: reserved $sku";
    }
}

PaymentService.php

class PaymentService
{
    public function charge(int $amount): string
    {
        return "payment: charged $amount";
    }
}

ShippingService.php

class ShippingService
{
    public function ship(string $city): string
    {
        return "shipping: to $city";
    }
}

OrderFacade.php

class OrderFacade
{
    public function __construct(
        private InventoryService $inventory,
        private PaymentService $payment,
        private ShippingService $shipping,
    ) {
    }

    public function place(string $sku, int $amount, string $city): string
    {
        return implode(' | ', [
            $this->inventory->reserve($sku),
            $this->payment->charge($amount),
            $this->shipping->ship($city),
        ]);
    }
}

demo.php

require_once 'InventoryService.php';
require_once 'PaymentService.php';
require_once 'ShippingService.php';
require_once 'OrderFacade.php';

$facade = new OrderFacade(
    new InventoryService(),
    new PaymentService(),
    new ShippingService(),
);

echo $facade->place('sku-1', 199, 'Berlin').PHP_EOL;

Example output

Running php demo.php in the terminal prints the three stages:

stock: reserved sku-1 | payment: charged 199 | shipping: to Berlin

Advantages

  • Provides a simple interface to a complex subsystem.
  • Reduces coupling: the client does not know the internal classes.
  • Hides the order and details of the subsystem.
  • A convenient single entry point for common operations.

When to use

  • When you need a simple interface to a complex subsystem.
  • When the subsystem has many interdependent classes.
  • When you want to layer a system and draw a boundary.
  • When a common scenario repeats and is worth wrapping.

Usage in Laravel

In Laravel the facade idea is illustrated by Illuminate\Support\Facades\Storage: a single entry point hides disks, Flysystem drivers and paths. The whole Illuminate\Support\Facades\* set (Cache, Mail, Log) provides a simple static API over managers and the container. Technically these are proxy-style facades, but they play exactly the simplifying role of a facade.