Design Pattern

Facade Pattern

Clean Java-only production-ready implementation.


What Problem It Solves

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.

Where Facade Appears in LLD Problems

  • Hotel Booking (#16): Facade combining search โ†’ pricing โ†’ booking โ†’ payment โ†’ confirmation
  • Ecommerce (#61): Facade for add-to-cart โ†’ checkout โ†’ payment โ†’ shipping โ†’ notification
  • Cab Sharing (#23): Facade for find-ride โ†’ match-driver โ†’ start-trip โ†’ complete โ†’ payment

Implementation

// โ”€โ”€โ”€ 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");
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...