The Facade Design Pattern provides a simple unified interface of a complex system to a client to abstract the complexity and make it easier for client to use.
Facade defines a single high level interface that makes the subsystem easier to use. Facade pattern comes under structural pattern as it provides one of the best ways to hide
internal complexities from client.
A facade is a composition of subsystems and uses delegates the tasks to subsystems. It may also add some logic of it's own before delegating work to subsystem. However, it doesn't hide the subsystem interfaces form the client. A client is free to directly interact with subsystem, it is on client whether to use facade or not.
In this tutorial, we'll explore the Facade Design Pattern in Java, covering its structure, implementation, best practices, and advantages.
Structure of the Facade Design Pattern
- Facade : This is the central class that provides a simplified and unified interface to the client. The facade delegates client requests to the appropriate subsystem components.
- Subsystem Classes : These are the individual classes or components that make up the subsystem. The facade doesn't encapsulate these classes but rather provides a higher-level interface to them.
- Client : This is the class or module that interacts with the facade to access the subsystem's functionality. The client is shielded from the complexities of the subsystem's internal structure.
Advantages of Facade Design Pattern
- Encapsulation of Subsystem Complexity : The pattern encapsulates the complexity of the subsystem, providing a layer of abstraction. Clients can focus on using the simplified interface provided by the facade without needing to understand the inner workings of the subsystem.
- Simplified Client Interface : The primary advantage of the Facade pattern is the simplification of the client interface. Clients interact with a unified facade, which shields them from the complexities and details of the subsystem.
- Enhanced Code Readability : The use of a facade enhances code readability by providing a clear and intuitive entry point for clients. The facade methods are named based on high-level operations, making it easier for developers to understand and use the subsystem.
- Promotion of Decoupling : The Facade pattern promotes decoupling between the client and the subsystem. Changes to the subsystem, including modifications to components or their internal structure, do not impact the client as long as the facade's interface remains consistent.
- Single Point of Contact for Clients : Clients have a single point of contact, the facade, through which they interact with the subsystem. This single point of contact contributes to a more organized and manageable system.
- Subsystem Evolution without Client Impact : Subsystem components can evolve independently of client code. As long as the facade's interface remains consistent, clients can adopt new versions of the subsystem without the need for modifications.
- Reduced Dependency on Subsystem Details : Clients are less dependent on the details of the subsystem. The facade shields clients from the specifics of individual components, promoting a separation of concerns.
When we should use Facade Pattern
- When we want to provide single unified interface to client to interact with a complex subsystem.
- When we want to hide the internal complexities of system.
- When we want to decouple the client's implementation form subsystems.
Implementation of Facade Design Pattern

First of all we will define the subsystems of a order fulfillment systems.
ReserveInventory.javaThis class reserves the item for this order.
public class ReserveInventory { public void reserveInventory(){ System.out.println("Blocking Item for Customer."); } }
ReservePayment.java
This class deducts the order amount form customers credit card.
public class ReservePayment { public void receivePayment(){ System.out.println("Deducting amount from customer's credit card."); } }
DeliverySystem.java
This class manages the delivery of an item to customers address.
public class DeliverySystem { public void deliverOrder(){ System.out.println("Deliverying Item to customer's address."); } }
CancelOrder.java
This class cancels customers order.
public class CancelOrder { public void cancelOrder(){ System.out.println("Cancelling order."); } }
RefundPayment.java
This class refunds the order amount to customer on order cancellation.
public class RefundPayment { public void refundOrderAmount(){ System.out.println("Refunding Order Amount to Customer."); } }
Now, to place an order we have to first reserve inventory and the reserve payment(deduct customers credit's card) and finally deliver the item to customer. To hide the complexity of placing order from a third party client we will provide a simple method "placeOrder" in OrderManagementFacade which will handle every thing required for placing an order. Similarly, we will provide "cancelOrder" method in facade for cancelling an order. Order Management Facade hides the complexities of fulfillment subsystems form client.
OrderManagementFacade.javapackage FacadePattern; public class OrderManagementFacade { private ReserveInventory reserveInventory; private ReservePayment reservePayment; private RefundPayment refundPayment; private DeliverySystem deliverySystem; private CancelOrder cancelOrder; public OrderManagementFacade(){ reserveInventory = new ReserveInventory(); reservePayment = new ReservePayment(); refundPayment = new RefundPayment(); deliverySystem = new DeliverySystem(); cancelOrder = new CancelOrder(); } public void placeOrder(){ reserveInventory.reserveInventory(); reservePayment.receivePayment(); deliverySystem.deliverOrder(); } public void cancelOrder(){ cancelOrder.cancelOrder(); refundPayment.refundOrderAmount(); } }
We will define a client class FacadePatternExample.java which will place and cancel the order using Order Management Facade.
FacadePatternExample.javapublic class FacadePatternExample { public static void main(String args[]){ OrderManagementFacade orderingSystem = new OrderManagementFacade(); // Place Order orderingSystem.placeOrder(); System.out.println("--------------------"); // Cancel Order orderingSystem.cancelOrder(); } }
Output
Blocking Item for Customer. Deducting amount from customer's credit card. Deliverying Item to customer's address. -------------------- Cancelling order. Refunding Order Amount to Customer.
Best Practices of Facade Design Pattern
- Design a clear and concise facade interface that hides the complexities of the subsystem from the client. The facade should provide a unified and intuitive interface that meets the client's needs.
- Provide granular methods in the facade that correspond to specific operations the client might perform. This granularity allows clients to interact with the subsystem at an appropriate level of abstraction.
- Encourage clients to interact with the subsystem exclusively through the facade. Avoid exposing subsystem components directly to clients, as this can lead to dependencies on specific implementations.
- Ensure that the facade encapsulates the details of the subsystem and shields the client from the internal structure of individual components. This encapsulation promotes a clean separation of concerns.
- Handle the initialization and configuration of subsystem components within the facade. This ensures that clients don't need to worry about configuring individual components and can rely on the facade for a simplified setup.
- Use consistent naming conventions for methods in the facade to enhance code readability. Clear and meaningful names contribute to an understanding of the facade's purpose and functionality.
- Design the facade and subsystem components to be flexible and extensible. This flexibility allows for the evolution of the subsystem without affecting the facade or requiring changes to client code.
- Keep the facade focused on providing a simplified interface to the subsystem and avoid introducing business logic within the facade. Business logic should reside in the subsystem components themselves.
- Clearly document the roles and responsibilities of individual subsystem components. Documentation helps developers understand the purpose and behavior of each component within the subsystem.
Bridge Design Pattern |
Mediator Design Pattern |
Interpreter Design Pattern |
Factory Design Pattern |
Prototype Design Pattern |
List of Design Patterns |