In this blog post, you’ll learn what’s the façade design pattern and how to apply it.
This post is part of the Design Patterns in Java Series. Check out the full list of covered patterns there.
Design patterns can seem a daunting subject to tackle, especially if we haven’t encountered them before.
With this in mind, I’ve chosen to start this series with one of the simplest patterns, namely the façade pattern.
Why Should You Use the Façade Design Pattern?
Let’s say you’re working on some cool new library for detecting faces in images.
I heard about your library and I want to use it in one of my projects.
Since you want to make your library easy to use, you write a method called getFacesInImage()
that takes an image as input and returns a list of locations where faces were detected in the image.
My code treats your library as a black-box so it’s not concerned with the details of how your algorithm actually detects the faces in the picture.
In this example, the getFacesInImage()
method is essentially an implementation of the façade pattern.
Here are a few usages of this pattern:
- Encapsulate logic and details of an app for clearness and security.
- Simplify access to a behind-the-scenes legacy system.
- Build a public API, such as a microservice API.
- Decrease network requests – a remote client makes one call to the façade, while the façade makes multiple calls to the underlying system.
What is a Façade?
The façade pattern is a structural design pattern that provides a simplified interface to a complex system.
It has two purposes:
-
Hides complex business logic from client code.
-
Decouples subsystem code from client code. This allows changes within the subsystem without affecting the client code.
Here’s the official definition from the Gang of Four book:
Provides a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.
I’d like to point out that interface in this context does not refer to the object-oriented concept of interface.
Instead, we’re talking about a layer of abstraction, a way of hiding low-level implementation details from an external user.
For example, a remote control would be an interface for controlling the TV.
We’re not really concerned about how the intricate electronic components of the TV work together, we just wanna know who died in the last Game of Thrones episode.
In fact, a universal remote control would allow us to have the same interface to a wide range of devices, thus shielding us from product details of multiple manufacturers.
Principle of Least Knowledge and the Façade
The façade pattern enforces the principle of Least Knowledge aka Law of Demeter, which states:
Only talk to your immediate friends.
Not a very good tip for meeting new people at a party, but a helpful guideline for promoting a loosely coupled software design.
The principle is enforced by reducing the amount of classes an object depends on.
This is illustrated in the diagram below. Observe how the client is only aware of the façade and not of the subsystem’s classes.
Façade Pattern Class Diagram
Pros
Below is a list of advantages of this pattern:
- loose coupling – the client has no knowledge of the subsystem.
- maintainability – changes are more manageable.
- simplicity – complexity is reduced by grouping related methods together, triggering them from a single, encompassing method.
Cons
A disadvantage of this pattern would be:
- runtime performance and code complexity – both can be negatively impacted if methods are unnecessarily wrapped in a façade. This leads to useless layers in the architecture.
How Can You Implement the Façade Pattern?
When it comes to implementation, any method that allows easy access to complex logic can be regarded as a façade.
Java Code Example
In the following example, I provide a Java implementation of the façade pattern.
Let’s say you want to invest speculate in Bitcoin. This would be a fairly complex business process involving other hypothetical classes such as BitcoinWallet
or BankAccount
.
The CryptocurrencyFacade
class simplifies this workflow by letting you call the investInBitcoin()
method.
We can see how the methods inside investInBitcoin()
are decoupled from the calling code.
Any changes in the façade’s complicated logic won’t affect the way the client calls the façade.
Summary
In conclusion, my three takeaways are:
-
The façade pattern encapsulates complex business logic.
-
The façade pattern decouples subsystems from clients.
-
Overuse of the façade design pattern can lead to a more complicated system due to the multiple layers added in the design.