Summary
Pattern Name | Facade Pattern |
Pattern Type | Structural Pattern |
Scope | Object |
Tagline | Unified interface to make subsystems easier to use |
Use cases | 1. When a simple interface is required for a complex system (distributed into subsystems) 2. When underlying complexity needs to be hidden from the client |
Related Patterns | Abstract Factory Mediator |
Difficulty Level | Easy |
Implementations |
Definition
Facade pattern adds a new layer of interface to a system, on top of the underlying complex subsystems interfaces.
Facade means – “the front of a building“.
Like, when we look at the front of a building, we do not get a complete idea of the actual structure of the building or other factors of the building.
Similarly, Facade pattern works as the front of a system, and the client does not have any idea what complexities are there in that underlying system.
Say, one part of the implementation of a system is divided into multiple subsystems. Then using and managing multiple subsystems directly from the client is difficult.
To reduce the complexity we can add a new layer to the implementation, which will communicate with the subsystems. This new layer works as an entry point for the client. The client can interact with this new layer, instead of communicating with the subsystems directly. That way the client does not need to be aware of the subsystems and gets a common interface.
All request from the client (the class which is using the subsystems) goes to the Facade, and then the facade talks to(uses the subsystem classes) the subsystems, get the result, and then return that to the client. So, the number of classes (or subsystems) that the client deals with is drastically reduced.
The subsystem modules/classes are not aware of the Facade, so no change is required in the subsystems. Everything is handled by the Facade.
There is no restriction to using the subsystem class directly from the client, the client can use the classes directly (but that is not the ideal case, as the Facade is implemented).
A Facade does not need to implement all the functionalities that the subsystem classes have. It only needs to implement the functionalities that the client(s) need.
Key points of Facade pattern are:
- Adds a unified interface to a set of interfaces.
- Hides underlying complexity from the client.
- Does not add any additional functionality.
- Facade support loose coupling. It decouples the client from the complements of a subsystem.
Facade pattern can be implemented at any point of the development process, when we realize that the system (or part of the system) has become very complex.
Use Cases
Here are the use cases of Facade Pattern –
- When we want to provide a simple interface to a complex/critical subsystem.
- When we want to reduce the number of classes, that the client deals with.
- When we want to make the subsystem independent (and portable).
- When we want the system to be layered, then we can define the Facade as the entry point to a layer.
Implementation
Here are the steps to implement Facade:
- Create a new class.
- Implement functionality that is required by the client class(es) in this new class.
- Make sure to implement all functionality required by the client, so that the client does not have to interact with the subsystem classes directly.
Examples
Example #1: Travel Plan
For example, let’s consider a system that represents a travel/transport process. For the implementation, we have a class (or maybe multiple classes) to operate a Car, and other classes for handling Map, Toll, and Weather:
- Car – handles the operation of a car, like, engine start/stop, driving, fuel calculation, etc.
- Map – handles the operation for getting the full route and what should be the next move.
- Toll – calculates toll at a certain part of travel.
- Weather – to get weather information.
We will create a Facade class named TravelFacade and will use the classes mentioned above in this facade.
Check the class diagram for this:
Here is the Pseudocode for this implementation –
Car Class
Car class implements the engine start/stop, go straight/left/right, etc.
class Car
function startEngine()
// Implement functionality
end function
function stopEngine()
// Implement functionality
end function
function goStraight()
// Implement functionality
end function
function goLeft()
// Implement functionality
end function
function goRight()
// Implement functionality
end function
function getDistanceTravelled()
// Implement functionality
end function
end class
Map Class
Map class has functions to get direction, distance, get information about certain locations, etc.
class Map
var startLat
var startLng
var endLat
var endLng
// define constructor
function Map(startLatParam, startLngParam, endLatParam, endLngParam)
set startLat = startLatParam
set startLng = startLngParam
set endLat = endLatParam
set endLng = endLngParam
end function
function getCurrentLocation()
// Implement functionality
end function
function getNextMove()
// Implement functionality
end function
function getFullRoute()
// Implement functionality
end function
function getLocationDetails(lat, lng)
// Implement functionality
end function
end class
Toll Class
Toll class is used to get the toll points and amount of toll.
class Toll
function getTollPoints(lat, lng)
// Implement functionality
end function
function getTollAmount(tollPointId)
// Implement functionality
end function
function getTotalToll(lat, lng)
// Implement functionality
end function
end class
Weather Class
Weather class is for getting the weather information:
class Weather
function getWeatherInfo(lat, lng)
// Implement functionality
end function
end class
Travel Facade
Let’s create TravelFacade class and implement all required functions:
class TravelFacade
var float startLat
var float startLng
var float endLat
var float endLng
var Map map
var Toll toll
var Car car
var Weather weather
// define constructor
function TravelFacade(startLatParam, startLngParam, endLatParam, endLngParam)
set startLat = startLatParam
set startLng = startLngParam
set endLat = endLatParam
set endLng = endLngParam
// Initialize classes
set map = new Map(startLat, startLng, endLat, endLng)
set car = new Car()
set toll = new Toll()
set weather = new Weather()
end function
function getRoute()
return map.getFullRoute()
end function
function getLocationInfo(lat, lng)
map.getLocationDetails(lat, lng)
weather.getWeatherInfo(lat, lng)
end function
function getCurrentLocation()
return map.getCurrentLocation()
end function
function operateCar()
set fullRoute = map.getFullRoute()
car.startEngine();
loop point in fullRoute
set nextMove = map.getNextMove()
if (nextMove == "straight") {
car.goStraight()
} else if (nextMove == "left") {
car.goLeft()
} else if (nextMove == "right") {
car.goRight()
}
end loop
car.stopEngine();
end function
function getTotalTollAmount(lat, lng)
return toll.getTotalToll(lat, lng))
end function
end class
Code Implementations
Use the following links to check Facade pattern implementation in specific programming languages.