Facade design pattern

Facade pattern is useful to hide the complex interactions between multiple coupled objects. For example, consider a shopping mall with offering different kind of services. Each store offers a single service or a combination of the services. Handling every possible combination can be complex. Facade pattern can help mask these complex interactions into one class and allow the user to only use one facade controller.

A shopping mall store can have any of the combination of the following functionalities depending on the kind of store.

class PaymentController {

    ...
    void handlePayment(Item item) {
        // Take money equivalent to the item's price.
        System.out.println("Payment processed");
    }
    ...
}

class ShippingController {

    ...
    void shipItem(Item item) {
        System.out.println("Item shipped");
    }
    ...
}

class OrderController {

    ...
    void processOrder(Item item) {
        System.out.println("Order processed");
    }
    ...
}

Every store in the shopping mall will one or more of these these instances. For instance, Cinema will only have OrderController and PaymentController. A clothing store may have all three of the classes.

class Cinema {

    ...
    private OrderController orderController;
    private PaymentController paymentController;
    ...
    void buyPopcorn(Item popcorn) {
        this.orderController.processOrder(popcorn);
    }
    ...
}

class ClothingStore {

    ...
    private OrderController orderController;
    private PaymentController paymentController;
    private ShippingController shippingController;
    ...
    void buyShirt(Item shirt) {
        this.orderController.processOrder(shirt);
    }

    void shipShirt(Item shirt) {
        this.shippingController.shipItem(shirt);
    }
    ...
}

Exposing all the controllers to each store can complicate the implementation. All the store’s functionality is delegated to their respective controllers. Hence, facade pattern is used to mask this complexity.

class ShoppingMallFacade {

    ...
    private OrderController orderController;
    private PaymentController paymentController;
    private ShippingController shippingController;
    ...

    void handlePayment(Item item) {
        this.paymentController.handlePayment(item);
    }

    void shipItem(Item item) {
        this.shippingController.shipItem(item);
    }

    void processOrder(Item item) {
        this.orderController.processOrder(item);
    }
    ...
}

The ShoppingMallFacade will contain all the essential controllers for a store to use. The stores can be simplified as they can just use this facade instead of the individual controllers.

class Cinema {

    ...
    private ShoppingMallFacade mallFacade;
    ...
    void buyPopcorn(Item popcorn) {
        this.mallFacade.processOrder(popcorn);
    }
    ...
}

class ClothingStore {

    ...
    private ShoppingMallFacade mallFacade;
    ...
    void buyShirt(Item shirt) {
        this.mallFacade.processOrder(shirt);
    }

    void shipShirt(Item shirt) {
        this.mallFacade.shipItem(shirt);
    }
    ...
}



Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Vendor lock-in Antipattern
  • Cut and Paste Programming Antipattern
  • Spaghetti Antipattern