Low Level Design

Facade Pattern — Simplify Complex Subsystems in Java

How the Facade pattern provides a single, clean entry point to a complex system of classes — hiding the internals and decoupling clients from subsystem details.

August 26, 2026·8 min read

What is the Facade Pattern?#

The Facade is a structural design pattern that provides a simplified, unified interface to a complex subsystem. It hides the complexities behind a single entry point.

The facade doesn't remove the complexity — it just keeps it out of the client's way.

You reach for Facade when:

  • A system has many classes that are complex to use directly
  • You want to provide a higher-level interface that makes a subsystem easier to work with
  • You need to decouple client code from the implementation details of the subsystem
  • You want a simple entry point for a library or framework

Real-World Analogy#

When you call customer care, you dial one number. The representative listens and internally coordinates with Billing, Technical Support, and Shipping departments to resolve your issue.

As a customer, you don't call each department separately. The representative (Facade) hides that complexity behind a single, friendly interface.


Class Diagram#


Violation Code — The Problem#

java
// Client knows too much about internal structure ❌
public class Client {
    public static void main(String[] args) {
        BillingDept billing = new BillingDept();
        TechSupportDept tech = new TechSupportDept();
        ShippingDept shipping = new ShippingDept();

        String issueType = "BILLING";

        if (issueType.equals("BILLING")) {
            billing.handleBillingIssue();
        } else if (issueType.equals("TECH")) {
            tech.handleTechIssue();
        } else if (issueType.equals("SHIPPING")) {
            shipping.handleShippingIssue();
        }
    }
}

Issues:

  1. Client knows too much — aware of all subsystem classes and their methods
  2. Tight coupling — if a department is renamed or refactored, the client breaks
  3. Code duplication — every client must repeat this orchestration
  4. No encapsulation — internal structure is fully exposed
  5. Violates OCP — adding a new department requires changing every client

Enhanced Code — Facade Pattern#

java
// Subsystem classes (unchanged)
public class BillingDept {
    public void handleBillingIssue() {
        System.out.println("Billing: resolving billing issue...");
    }
}

public class TechSupportDept {
    public void handleTechIssue() {
        System.out.println("Tech Support: resolving technical issue...");
    }
}

public class ShippingDept {
    public void handleShippingIssue() {
        System.out.println("Shipping: resolving shipping issue...");
    }
}

// Facade — the single entry point
public class CustomerCare {
    private final BillingDept billing;
    private final TechSupportDept tech;
    private final ShippingDept shipping;

    public CustomerCare() {
        this.billing  = new BillingDept();
        this.tech     = new TechSupportDept();
        this.shipping = new ShippingDept();
    }

    public void resolveIssue(String type) {
        switch (type.toUpperCase()) {
            case "BILLING":  billing.handleBillingIssue();    break;
            case "TECH":     tech.handleTechIssue();          break;
            case "SHIPPING": shipping.handleShippingIssue();  break;
            default: System.out.println("Unknown issue type: " + type);
        }
    }
}

// Client — only knows about CustomerCare ✅
public class Main {
    public static void main(String[] args) {
        CustomerCare care = new CustomerCare();
        care.resolveIssue("BILLING");
        care.resolveIssue("TECH");
        care.resolveIssue("SHIPPING");
    }
}

Adding a new department → update the facade only. Client code never changes.


Common LLD Problems Using Facade Pattern#

1. Home Theater System#

  • Facade: HomeTheaterFacade
  • Subsystems: DVD Player, Projector, Sound System, Lights, Curtains
  • Context: watchMovie("Inception") orchestrates all subsystems — one call, full setup.

2. E-commerce Checkout#

  • Facade: CheckoutFacade
  • Subsystems: Cart, Inventory, Payment, Shipping, Notification
  • Context: checkout(cart, user) handles the full purchase flow.

3. Banking Application#

  • Facade: BankServiceFacade
  • Subsystems: Account, Loan, Credit, Ledger, Notification
  • Context: transferFunds(from, to, amount) orchestrates debit, credit, and ledger updates.

4. Online Travel Booking#

  • Facade: TravelBookingFacade
  • Subsystems: Flight, Hotel, Car Rental, Payment
  • Context: bookTrip(destination, dates) books everything in one call.

5. Smart Home Automation#

  • Facade: SmartHomeFacade
  • Subsystems: Lights, AC, Curtains, TV, Security Camera
  • Context: leaveHome() → turns off lights, lowers AC, locks doors, arms cameras.

6. Document Conversion Tool#

  • Facade: DocumentConverterFacade
  • Subsystems: PDF processor, Word processor, Image processor
  • Context: convert("doc.docx", "PDF") handles all format-specific logic internally.

7. Hospital Management System#

  • Facade: HospitalFacade
  • Subsystems: Patient Records, Billing, Pharmacy, Lab Tests, Notifications
  • Context: admitPatient(patient) coordinates all departments seamlessly.

8. Social Media Integration#

  • Facade: SocialMediaFacade
  • Subsystems: Twitter API, Facebook API, LinkedIn API
  • Context: post(content) publishes to all platforms through one call.

Facade vs Adapter#

FacadeAdapter
IntentSimplify a complex subsystemBridge an incompatible interface
InterfaceCreates a new simplified oneTranslates an existing one
ScopeWraps many classesTypically wraps one class
Problem solvedToo much complexityInterface mismatch

ReferencesLinks
Article ReferenceRefactoring Guru — Facade