Java > Design Patterns in Java > Structural Patterns > Facade Pattern
Facade Pattern Example: Order Processing System
This code demonstrates the Facade pattern in Java. The Facade pattern provides a simplified interface to a complex subsystem. In this example, we simulate an order processing system, where multiple components (Inventory, Payment, Shipping) are involved. The OrderFacade simplifies the process of placing an order by hiding the complexities of these underlying components.
OrderFacade Class
The OrderFacade
class acts as a facade. It encapsulates the complex interaction between the Inventory
, Payment
, and Shipping
subsystems. The placeOrder
method provides a simplified interface for placing an order. The client only interacts with the facade, not the individual subsystems directly.
public class OrderFacade {
private Inventory inventory;
private Payment payment;
private Shipping shipping;
public OrderFacade() {
this.inventory = new Inventory();
this.payment = new Payment();
this.shipping = new Shipping();
}
public void placeOrder(String productId, int quantity, String paymentDetails, String shippingAddress) {
if (inventory.checkAvailability(productId, quantity)) {
if (payment.processPayment(paymentDetails)) {
shipping.shipProduct(productId, quantity, shippingAddress);
System.out.println("Order placed successfully!");
} else {
System.out.println("Payment failed. Order not placed.");
}
} else {
System.out.println("Product out of stock. Order not placed.");
}
}
}
Inventory Subsystem
The Inventory
class represents one of the subsystems. It handles checking the availability of products. In a real-world scenario, this class would interact with a database or other inventory management system.
class Inventory {
public boolean checkAvailability(String productId, int quantity) {
// Simulate checking inventory
System.out.println("Checking inventory for product " + productId + ", quantity: " + quantity);
return quantity <= 10; // Simulate limited stock
}
}
Payment Subsystem
The Payment
class represents the payment subsystem. It handles processing payments. In a real-world scenario, this class would interact with a payment gateway.
class Payment {
public boolean processPayment(String paymentDetails) {
// Simulate processing payment
System.out.println("Processing payment with details: " + paymentDetails);
return true; // Simulate successful payment
}
}
Shipping Subsystem
The Shipping
class represents the shipping subsystem. It handles shipping products. In a real-world scenario, this class would interact with a shipping provider.
class Shipping {
public void shipProduct(String productId, int quantity, String shippingAddress) {
// Simulate shipping product
System.out.println("Shipping product " + productId + ", quantity: " + quantity + " to address: " + shippingAddress);
}
}
Client Code
The Main
class demonstrates how to use the OrderFacade
. The client code only needs to interact with the facade, simplifying the order placement process.
public class Main {
public static void main(String[] args) {
OrderFacade orderFacade = new OrderFacade();
orderFacade.placeOrder("Product123", 5, "Credit Card", "123 Main St");
}
}
Concepts Behind the Snippet
The Facade pattern aims to reduce the complexity of interacting with a complex system. It provides a higher-level interface that makes the subsystem easier to use. The key concept is encapsulation of complex interactions behind a simpler interface.
Real-Life Use Case
A common real-life use case is a compiler. A compiler takes source code as input and transforms it into executable code. This process involves multiple phases like lexical analysis, parsing, semantic analysis, code generation, and optimization. A facade can provide a simple compile()
method that orchestrates all these phases, hiding the complexity from the user.
Best Practices
When to Use Them
Use the Facade pattern when:
Pros
Cons
FAQ
-
What is the difference between Facade and Adapter pattern?
The Facade pattern provides a simplified interface to a complex subsystem, hiding the complexity from the client. The Adapter pattern, on the other hand, allows incompatible interfaces to work together. It converts the interface of a class into another interface clients expect.
-
Is the Facade pattern similar to an API?
Yes, the Facade pattern can be seen as a simplified API for a subsystem. It provides a well-defined entry point for clients to interact with the complex underlying components.