In this series of Java design pattern, we will look at the Facade design pattern. It is one of the Structural Design patterns that simplifies the interface to a library, framework, or any other complex set of classes.
Facade Design Pattern
A Facade design pattern is a structural design pattern that simplifies the interface to a library, framework, or any other complex set of classes.A façade is a class that gives a straightforward interface to a complicated subsystem with many moving pieces. When compared to interacting directly with the subsystem, a facade may have limited capabilities. It does, however, only include the elements that clients care about. This design pattern uses a single class to provide client-side simplified methods while delegating calls to existing system classes’ functions.
When you need to integrate your app with a complicated library with dozens of functions but only require a small portion of them, having a facade comes in helpfully.
Let’s inspect a few important components of the facade design pattern.
1.1. Facade Class
The Facade facilitates access to a certain aspect of the subsystem’s functionality. It understands where the client’s request should be directed and how to run all the moving elements.
1.2. Additional Facade Class
To avoid cluttering a single facade with unrelated features that could turn it into yet another complex structure, we can build an Additional Facade class. Clients and other facades can both use additional facades.
1.3. Sub-System Classes
The Complex Subsystem comprises many objects. To make them all do anything useful, you’ll need to get into the nitty-gritty of the subsystem’s implementation, such as correctly initializing objects and supplying them with data in the right format.The façade isn’t visible to the subsystem classes. They work within the system and directly with one another.
1.4. Client
Instead of calling the subsystem objects directly, the Client uses the façade.
2. Facade Design Pattern in Java
Let’s build the facade design pattern in Java. This will give us an overview of the different Java classes while using this design pattern. We’ll make an IMobileShop
interface and concrete classes that implement the Shape
interface, i.e., iPhone, Samsung, and Nokia. As a next step, the facade class ShopKeeper
is defined. The ShopKeeper
class uses the concrete classes to delegate user calls to these classes. Our demo class, FacadePatternClient
, will use the ShopKeeper
class to display the results.
public interface IMobileShop {
/**
* Mobile Model Number
*/
public void getMobileModelNumber();
/**
* Mobile Price
*/
public void getMobilePrice();
}
Create an implementation class for the iPhone
that implements the IMobileShop
interface.
public class Iphone implements IMobileShop {
@Override
public void getMobileModelNumber() {
System.out.println("The model is: IPhone 13");
}
@Override
public void getMobilePrice() {
System.out.println("The price is: 75000INR ");
}
}
Create an implementation class for Samsung
that implements the IMobileShop
interface.
public class Samsung implements IMobileShop {
@Override
public void getMobileModelNumber() {
System.out.println("The model is: Galaxy 11");
}
@Override
public void getMobilePrice() {
System.out.println("The price is: 85000INR ");
}
}
Create an implementation class for Nokia
that implements the IMobileShop
interface.
public class Nokia implements IMobileShop {
@Override
public void getMobileModelNumber() {
System.out.println("The model is: Nokia 1100");
}
@Override
public void getMobilePrice() {
System.out.println("The price is: 1500INR ");
}
}
Finally, create a concrete ShopKeeper
class that uses the IMobileShop
interface.
public class ShopKeeper {
private IMobileShop iphone;
private IMobileShop samsung;
private IMobileShop nokia;
/**
* no args constructor
*/
public ShopKeeper() {
iphone = new Iphone();
samsung = new Samsung();
nokia = new Nokia();
}
public void iphonePhoneSale() {
iphone.getMobileModelNumber();
iphone.getMobilePrice();
}
public void samsungPhoneSale() {
samsung.getMobileModelNumber();
samsung.getMobilePrice();
}
public void nokiaPhoneSale() {
nokia.getMobileModelNumber();
nokia.getMobilePrice();
}
}
2.1. FacadePatternClient Class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class FacadePatternClient {
private static int choice;
public static void main(String args[]) throws NumberFormatException, IOException {
do {
System.out.print("========= Mobile Shop ============ \n");
System.out.print("1. IPHONE. \n");
System.out.print("2. SAMSUNG. \n");
System.out.print("3. NOKIA. \n");
System.out.print("4. Exit. \n");
System.out.print("Enter your choice: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
choice = Integer.parseInt(br.readLine());
ShopKeeper shopKeeper = new ShopKeeper();
switch (choice) {
case 1:
{
shopKeeper.iphonePhoneSale();
}
break;
case 2:
{
shopKeeper.samsungPhoneSale();
}
break;
case 3:
{
shopKeeper.nokiaPhoneSale();
}
break;
default:
{
System.out.println("Nothing You purchased");
}
return;
}
} while (choice != 4);
}
}
Output
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. NOKIA.
4. Exit.
Enter your choice: 1
The model is: IPhone 13
The price is: 75000INR
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. NOKIA.
4. Exit.
Enter your choice: 2
The model is: Galaxy 11
The price is: 85000INR
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. NOKIA.
4. Exit.
Enter your choice: 3
The model is: Nokia 1100
The price is: 1500INR
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. NOKIA.
4. Exit.
Enter your choice: 4
Nothing You purchased
Process finished with exit code 0
This is how the class digram looks like for the facade design pattern
3. Advantages and Disadvantages
Let’s look at some advantages and disadvantages of using the facade pattern.
- It protects customers from the sub-system components’ intricacies.
- It encourages subsystems and clients to be loosely coupled.
Some disadvantages of using facade design pattern
- Apart from building a complex structure, there are no obvious disadvantages to the Façade design pattern.
3.1 When to use Facade Design Pattern
- When you have a sophisticated system that you wish to expose to clients simply, or when you want to create an external communication layer over an existing system that is incompatible with the system, the facade pattern is ideal.
- Facade is concerned with user interfaces rather than implementation. Its goal is to disguise internal complexity behind a single, simple-looking interface on the outside.
- When there are several dependencies between clients and an abstraction’s implementation classes.
Summary
In this post, we talked about the Facade Design Pattern. We saw some of the real-world examples along with what are some advantages of using this pattern. We also saw a Java implementation for this design pattern. You can always check our GitHub repository for the latest source code. Here is an example from the JDK using the same design pattern.
javax.faces.context
->FacesContext
employs abstract/interface classes such asLifeCycle
,ViewHandler
,NavigationHandler
, and many others internally, so the end-user doesn’t have to worry about it (overridable by injection).
javax.faces.context
-> Internally,ExternalContext
employsServletContext
,HttpSession
,HttpServletRequest
, andHttpServletResponse
.