Facade pattern
Facade pattern is one of the structural design patterns.
This pattern simplifies the interface to a complex system
In other words,It provides a unified interface to a set of interfaces in a subsystem.
It is usually composed of all the classes which make up the subsystems of the complex system
A Facade pattern shields the user from the details of the complex system and provides them with a simplified view of it which is easy to use.
It also decouples the code that uses the system from the details of the subsystems, making it easier to modify the system later.
Façade
It acts as a intermediatery between clinet and complex system
Knows which subsystem classes are responsible for a request
Delegates client requests to appropriate subsystem objects.
Subsystem
Main classes having defined responsibility within the complex system
Handle the work assigned by Facade object
Have no knowledge of the facade and keep no reference to it
Note: Façade will keep the references to each component of complex system but subsystem will not keep façade references.
Let’s implement this pattern for below requirement
Requirement :
In ecommerce site, Client places a request for placing the order
Now order should be persisted in backend, client should get confirmation on the screen and also they should receive an order confirmation email.
Step 1
Create 2 interfaces – one for order persisting and other one for sending order confirmation email
- package com.kb.facade;
- public interface OrderService {
- public abstract void createOrder();
- }
package com.kb.facade; public interface OrderService { public abstract void createOrder(); }
- package com.kb.facade;
- public interface EmailService {
- public abstract void sendEmail();
- }
package com.kb.facade; public interface EmailService { public abstract void sendEmail(); }
Step 2
Define 2 service classes by Implementing the above interfaces
- package com.kb.facade;
- public class OrderServiceImpl implements OrderService{
- @Override
- public void createOrder() {
- System.out.println("Order is created");
- }
- }
package com.kb.facade; public class OrderServiceImpl implements OrderService{ @Override public void createOrder() { System.out.println("Order is created"); } }
- package com.kb.facade;
- public class EmailServiceImpl implements EmailService{
- @Override
- public void sendEmail() {
- System.out.println("Order confirmation email sent");
- }
- }
package com.kb.facade; public class EmailServiceImpl implements EmailService{ @Override public void sendEmail() { System.out.println("Order confirmation email sent"); } }
Step 3
Create a façade which uses these interfaces
- package com.kb.facade;
- public class OrderFacade {
- private OrderService orderService = new OrderServiceImpl();
- private EmailService emailService = new EmailServiceImpl();
- public void placeOrder(){
- orderService.createOrder();
- emailService.sendEmail();
- }
- }
package com.kb.facade; public class OrderFacade { private OrderService orderService = new OrderServiceImpl(); private EmailService emailService = new EmailServiceImpl(); public void placeOrder(){ orderService.createOrder(); emailService.sendEmail(); } }
We know that façade will have references to set of interfaces
In the above façade, we are making references to 2 interfaces namely OrderService and EmailService
Note : These instances references can be injected in spring xml if we use spring project
Now client using this façade will just make a call to single method of façade “placeOrder”
Façade communicates with the underlying subsystem and gets the order persisted and email sent to customer.
Step 4
Create a client class which use this Façade
- package com.kb.facade;
- public class FacadeClient {
- public static void main(String[] args) {
- OrderFacade orderFacade = new OrderFacade();
- System.out.println("Output with facade");
- orderFacade.placeOrder();
- //Achieveing the above functionality without facade
- OrderService orderService = new OrderServiceImpl();
- EmailService emailService = new EmailServiceImpl();
- System.out.println("Output without facade");
- orderService.createOrder();
- emailService.sendEmail();
- }
- }
package com.kb.facade; public class FacadeClient { public static void main(String[] args) { OrderFacade orderFacade = new OrderFacade(); System.out.println("Output with facade"); orderFacade.placeOrder(); //Achieveing the above functionality without facade OrderService orderService = new OrderServiceImpl(); EmailService emailService = new EmailServiceImpl(); System.out.println("Output without facade"); orderService.createOrder(); emailService.sendEmail(); } }
We can see the same output is produced using façade and without using façade
When we use façade, we just need to call single method of façade and rest is taken care by façade
When we don’t use façade, we need to call 2 methods in the client.
This is not too complex system used in this example, think of highly complex system in real time and there is a real demand of Facade design pattern.
When to use facade pattern
It can be used at any point of development, but it’s very important to use when number of interfaces grow and system gets complex.
It should be used for similar kind of interfaces which means having related functionality.
It should be used when we want to provide a single interface rather than multiple interfaces that does the similar kind of jobs.
It should be used when we want to provide simple interface to client system to interact with a complex system