Facade Design Pattern in Java

1. Definition

The Facade Design Pattern provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use by external clients.

2. Problem Statement

Consider a scenario where a client application interacts with a complex system which has multiple subsystems. Having the client interact with each subsystem directly can result in tight coupling, making the system harder to manage and understand.

3. Solution

Introduce a facade that acts as an entry point to various subsystems. The facade simplifies and unifies the interfaces, making the subsystems easier to use without changing the subsystems themselves.

4. Real-World Use Cases

1. A home theater system where the facade simplifies turning on the projector, sound system, lowering blinds, etc., with a single "watch movie" command.

2. Online shopping systems where the facade can handle complex processes like inventory check, payment, and shipping.

5. Implementation Steps

1. Identify a simpler, unified interface that can encapsulate interactions with various subsystems.

2. Implement the facade which delegates client requests to appropriate subsystem objects.

3. Clients communicate with the subsystems only through the facade.

6. Implementation

// Subsystem 1
class Inventory {
    public boolean isAvailable(String product) {
        // Check warehouse database for product availability.
        return true;
    }
}

// Subsystem 2
class Payment {
    public boolean processPayment(String orderID) {
        // Process payment.
        return true;
    }
}

// Subsystem 3
class Shipping {
    public void shipProduct(String product) {
        // Ship the product.
    }
}

// Facade
class OrderServiceFacade {
    private Inventory inventory = new Inventory();
    private Payment payment = new Payment();
    private Shipping shipping = new Shipping();

    public boolean placeOrder(String productID) {
        if (!inventory.isAvailable(productID)) return false;
        if (!payment.processPayment(productID)) return false;
        shipping.shipProduct(productID);
        return true;
    }
}

// Client code
public class FacadePatternDemo {
    public static void main(String[] args) {
        OrderServiceFacade orderService = new OrderServiceFacade();
        boolean orderPlaced = orderService.placeOrder("1234");
        System.out.println("Order placed successfully: " + orderPlaced);
    }
}

Output:

Order placed successfully: true

Explanation

In this example, the OrderServiceFacade acts as a unified interface to various subsystems involved in placing an order. The client doesn't need to know the intricacies of inventory checking, payment processing, or shipping. It simply interacts with the facade to place an order.

7. When to use?

Use the Facade Pattern when:

1. You want to provide a simplified interface to a complex subsystem.

2. There are many dependencies between clients and the implementation classes of an abstraction.

3. You want to layer your subsystems. The facade can define entry points to each level of a system.


Comments