Design Pattern

Facade Pattern

Clean Java-only production-ready implementation.


A subsystem has many classes with complex interactions. The client needs a simple, unified interface to perform a common task without knowing the internal complexity.

// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A smart home cinema controller turning on projectors, adjusting lights, and
// loading movies in one click.
//
// WHERE THE FACADE FITS IN:
// HomeTheaterFacade acts as the Facade, wrapping complex subsystems
// (Projector, SoundSystem, Lights) to expose a single watchMovie() method.
// ────────────────────────────────────────────────────────────────────────────
// --- Complex subsystem ---
class InventoryService {
    public boolean checkAvailability(String itemId, int qty) {
        System.out.println("  [Inventory] Checking stock for " + itemId);
        return true;
    }
    public void reserve(String itemId, int qty) {
        System.out.println("  [Inventory] Reserved " + qty + " of " + itemId);
    }
}

class PaymentService {
    public boolean charge(String userId, double amount) {
        System.out.println("  [Payment] Charging " + userId + " $" + amount);
        return true;
    }
}

class ShippingService {
    public String createShipment(String orderId, String address) {
        System.out.println("  [Shipping] Creating shipment for " + orderId);
        return "TRACK-" + orderId;
    }
}

class NotificationService {
    public void sendConfirmation(String email, String orderId) {
        System.out.println("  [Notif] Confirmation sent to " + email + " for " + orderId);
    }
}

// --- Facade ---
class OrderFacade {
    private final InventoryService inventory = new InventoryService();
    private final PaymentService payment = new PaymentService();
    private final ShippingService shipping = new ShippingService();
    private final NotificationService notif = new NotificationService();

    public String placeOrder(String userId, String itemId, int qty, double price, String address, String email) {
        System.out.println("  [Facade] Processing order...");
        if (!inventory.checkAvailability(itemId, qty)) return "OUT_OF_STOCK";
        inventory.reserve(itemId, qty);
        if (!payment.charge(userId, price)) {
            System.out.println("  [Facade] Payment failed — order aborted");
            return "PAYMENT_FAILED";
        }
        String tracking = shipping.createShipment("ORDER-" + itemId, address);
        notif.sendConfirmation(email, "ORDER-" + itemId);
        System.out.println("  [Facade] Order complete. Tracking: " + tracking);
        return tracking;
    }
}

public class Main {
    public static void main(String[] args) {
        OrderFacade facade = new OrderFacade();
        facade.placeOrder("user-42", "ITEM-001", 2, 49.99, "123 Main St", "alice@email.com");
    }
}