Facade  Pattern - Java - Explained

Facade Pattern - Java - Explained

Intent

The Facade 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.

Facade pattern express the "Principle of least knowledge" which guide us to reduce the interactions between objects to just an object which can help interact with other useful objects.

Facade does not usually restrict access to sub-systems rather it put convention in some cases not to use it without facade when possible.

Motivation behind the pattern/problem it solves?

  1. Structuring a complex system into small manageable subsystems definitely reduces complexity. The facade pattern helps introduce a unified interface to manage all small manageable subsystems which then reduce complexity in terms of managing all those resources.

  2. Do you want to introduce a layered approach to manage a complex system, then a facade pattern helps achieve that. Facade patter provides the ability to have an entry points into your layers so that client which is using layer only knows about your facade which is easier to use.

  3. If you want to decouple the subsystems in your complex application then consider using facade pattern.

Design Problem - Facade pattern

Consider you are developing a enterprise ecommerce application, you have many business objects (services) like userService, shippingService, paymentService, inventoryService, placeOrderService, and taxService. All these are used in different scenarios like if we want to write a function for add to cart then userService, inventoryService and taxService is used.
We want to provide a scalable and maintainable solution.

solution approach 1 : without using facade .

Please refer below diagram where each of the function which uses subsystems have to instantiate it and use it. doesn't it looks tightly coupled design?

image.png

solution approach 2 : using facade pattern

Refer below diagram, here we have introduced a facade class which is 'll act like unified interface to access underlying subsystem classes(services in our case) .
Doing this 'll help us to decouple direct access to underlying services, also we can introduce some methods in the facade class which can help to do some basic validation before actually using subsystems.

image.png

Facade actually defines high level interface which makes subsystems easier to use in our code we have defined CartFacade as high level interface which helps us to use underlying services classes

public class FacadePatternMain {
    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
        CartFacade cartFacade = applicationContext.getBean(CartFacade.class);

        // adding product to cart facade is used to call related services in the respective business logic specific methods.
        cartFacade.addProductToCart();
    }
}

@Component
public class CartFacade {

    @Autowired
    UserService userService;

    @Autowired
    TaxService taxService;

    @Autowired
    ShippingService shippingService;

    @Autowired
    PlaceOrderServices placeOrderServices;

    @Autowired
    PaymentService paymentService;

    @Autowired
    InventoryService inventoryService;


    public void addProductToCart() {
        //TODO using services and adding product to cart goes here
        getUserService().isRegisteredCustomer();
        getInventoryService().isProductAvailableInStock();

    }

    public void removeProductFromCart() {
        //TODO using services and removing product from cart
    }

    public void placeOrderForCart() {
        //TODO using services placing order for an cart
    }

    protected UserService getUserService() {
        return this.userService;
    }

    protected TaxService getTaxService() {
        return this.taxService;
    }

    protected ShippingService getShippingService() {
        return this.shippingService;
    }

    protected PlaceOrderServices getPlaceOrderServices() {
        return this.placeOrderServices;
    }

    protected PaymentService getPaymentService() {
        return this.paymentService;
    }

    public InventoryService getInventoryService() {
        return this.inventoryService;
    }
}

check here for code on git

Structure of Facade pattern

Actor : its a client which want to use subsystems
Facade class : Its an unified interface to access related services.
subsystems : it contains many business services.

Structure is simple , its basically used to decouple services add layered approach which makes it more readable and maintainable code.

Pros and Cons

Pros

  1. Helps to achieve layered approach
  2. Complex subsystems can be manageable better with unified interface.
  3. Helps to provide abstraction and manage complexities in unified exposed facade class to client.

Cons

  1. Adds unnecessary layer if your application is not very complex.

Relation with other patterns

  1. Facade vs Adaptor
    Adaptor makes existing interface usable however in facade we create new interface and group all related method calls together.

  2. Facade and Mediator are usually same, they try to organize collaboration between lots of tightly coupled classes.

  3. usually facade objects are singleton as only one unified interface is expected.

Thanks for reading. Love IT Live IT Enjoy IT.