Facade Pattern
Provide a simple, unified interface to a complex subsystem so clients don't need to know its internals.
Intent
Facade offers one high-level entry point to a set of lower-level classes. Clients call placeOrder(...) instead of orchestrating inventory, payment, shipping and notification services themselves. The subsystem classes remain available for clients that need fine-grained control — the facade just makes the common case easy.
Structure
classDiagram
direction LR
class OrderFacade {
+placeOrder(customer, sku, qty) String
}
class InventoryService {
+reserve(sku, qty) boolean
}
class PaymentService {
+charge(customer, amount) String
}
class ShippingService {
+schedule(customer, sku) String
}
class EmailService {
+sendConfirmation(customer, ref)
}
Client --> OrderFacade
OrderFacade --> InventoryService
OrderFacade --> PaymentService
OrderFacade --> ShippingService
OrderFacade --> EmailService
Example
import java.util.*;
// ---- A subsystem with several moving parts ----
class InventoryService {
private final Map<String, Integer> stock = new HashMap<>(Map.of("BOOK-1", 10, "MUG-7", 0));
boolean reserve(String sku, int qty) {
int available = stock.getOrDefault(sku, 0);
if (available < qty) return false;
stock.put(sku, available - qty);
return true;
}
void release(String sku, int qty) { stock.merge(sku, qty, Integer::sum); }
}
class PricingService {
double priceOf(String sku) { return sku.startsWith("BOOK") ? 24.99 : 9.99; }
}
class PaymentService {
String charge(String customer, double amount) {
if (amount > 100) throw new IllegalStateException("Card limit exceeded");
return "PAY-" + Math.abs((customer + amount).hashCode() % 10000);
}
}
class ShippingService {
String schedule(String customer, String sku) { return "SHIP-" + sku.hashCode() % 1000; }
}
class EmailService {
void send(String to, String text) { System.out.println(" ✉ to " + to + ": " + text); }
}
// ---- The facade: one method that orchestrates the workflow ----
class OrderFacade {
private final InventoryService inventory = new InventoryService();
private final PricingService pricing = new PricingService();
private final PaymentService payments = new PaymentService();
private final ShippingService shipping = new ShippingService();
private final EmailService email = new EmailService();
String placeOrder(String customer, String sku, int qty) {
if (!inventory.reserve(sku, qty)) return "FAILED: " + sku + " out of stock";
try {
String payment = payments.charge(customer, pricing.priceOf(sku) * qty);
String shipment = shipping.schedule(customer, sku);
email.send(customer, "Order confirmed (" + payment + ", " + shipment + ")");
return "OK: " + payment;
} catch (RuntimeException e) {
inventory.release(sku, qty); // compensate on failure
return "FAILED: " + e.getMessage();
}
}
}
class Main {
public static void main(String[] args) {
var shop = new OrderFacade();
System.out.println(shop.placeOrder("ada@example.com", "BOOK-1", 2));
System.out.println(shop.placeOrder("bob@example.com", "MUG-7", 1));
System.out.println(shop.placeOrder("cy@example.com", "BOOK-1", 5));
}
}Facade in Spring applications
In a typical Spring Boot service, an application service is a facade: a @Service method annotated with @Transactional that coordinates repositories, domain objects and external clients for one use case. Controllers call the facade; they never orchestrate repositories directly.
@Service
@RequiredArgsConstructor
public class CheckoutService { // facade over the ordering subsystem
private final InventoryClient inventory;
private final PaymentClient payments;
private final OrderRepository orders;
private final ApplicationEventPublisher events;
@Transactional
public OrderId checkout(CheckoutCommand cmd) { /* orchestrate */ }
}
Where you’ll see it
javax.faces.context.FacesContext,java.net.URL.openStream()(hidesURLConnection, protocol handlers and streams)- Spring’s
JdbcTemplate— a facade overDataSource,Connection,PreparedStatement,ResultSetand exception translation - SLF4J’s
LoggerFactory(also a Bridge) - The API Gateway / Backend-for-Frontend pattern in microservices is a facade at architectural scale
Mark it complete to track your progress through Design Patterns.