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.
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#
// 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:
- Client knows too much — aware of all subsystem classes and their methods
- Tight coupling — if a department is renamed or refactored, the client breaks
- Code duplication — every client must repeat this orchestration
- No encapsulation — internal structure is fully exposed
- Violates OCP — adding a new department requires changing every client
Enhanced Code — Facade Pattern#
// 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#
| Facade | Adapter | |
|---|---|---|
| Intent | Simplify a complex subsystem | Bridge an incompatible interface |
| Interface | Creates a new simplified one | Translates an existing one |
| Scope | Wraps many classes | Typically wraps one class |
| Problem solved | Too much complexity | Interface mismatch |
| References | Links |
|---|---|
| Article Reference | Refactoring Guru — Facade |