0:15
As parts of your system become larger,
they naturally become more complex.
This can be potentially confusing for the client classes in your system to use.
System complexity is not always a sign of poor design, though.
The scope of the problem you're trying to solve may be so large,
it requires a complex solution.
Client classes, however, would prefer a simpler interaction.
The facade design pattern provides
a single simplified interface for client classes to interact with the subsystem.
What is a facade?
If you've ever gone shopping at a retail store, eaten at a restaurant,
or ordered anything online,
you've had experience interacting with the real world facade design pattern.
Picture yourself walking down the street looking for a place to have dinner.
What do you look for when you're at street level?
Naturally, you look for a sign on the face of a building that
indicates that the contents within the structure can provide you with the dining service.
Similarly, when you're shopping online,
you look for some outward indication that the website you're on has a virtual storefront.
These outward facing indicators are used to
communicate to the public what types of services are available.
When a waiter takes and places your order,
or when an online sales platform sends your order to be fulfilled,
they are acting as part of a facade by
hiding away all the extra work that needs to be done.
You are able to purchase goods and services without
having to know how the request is processed.
The entire construction of the buildings, wait-staff, menus,
websites and many other components are behind facades.
Keep in mind that a facade does not actually add more functionality,
a facade simply acts as a point of entry into your subsystem.
In software, the facade design pattern does
exactly what a waiter or salesperson would do in real life.
A facade is a wrapper class that encapsulate
the subsystem in order to hide the subsystem's complexity.
This wrapper class will allow a client class to interact with
the subsystem through a facade.
Let's take a look at how client code would interact with
the subsystem without a facade class for a simple banking system.
Without a facade class,
the customer class would contain instances of the checking,
saving and investment classes.
This means that the customer is responsible for properly instantiating each of
these constituent classes and knows about all their different attributes and methods.
This is like having to manage all of your own financial accounts in real life,
which can be complex with lots of accounts,
instead of letting a financial institution do it for you.
Instead, we introduce the bank service class to act as a facade for the checking,
saving, and investment classes.
The customer class no longer needs to handle instantiation
or deal with any of the other complexities of financial management.
Since the three different accounts all implement the IAccount interface,
the bank's service class is effectively wrapping the account interfacing classes,
and presenting a simpler front to them for the customer client class to use.
The facade design pattern is simple to apply in our bank accounts example.
It combines interface implementation by
one or more classes which then gets wrapped by the facade class.
Let's see how to do that.
Step one. Design the interface.
This Java interface is the one that will be implemented by
the different account classes and will not be known to the customer class.
Step two.
Implement the interface with one or more classes.
Remember that interfaces allow us to create subtypes which means that checking, saving,
and investment are subtypes of i-Account and are expected to behave like an account type.
Next, you implementer interface with classes that will be wrapped with our facade class.
In this example, you are only implementing and hiding one interface,
but in practice, a facade class can be used to
wrap all the interfaces and classes for a subsystem.
It is your decision as to what you want to wrap.
Step three. Create the facade class and wrap the classes that implement the interface.
The bank service class is the facade.
How does it do that?
Notice that its public methods are simple to use and show
no hint of the underlying interface and implementing classes.
Another thing to note is that we set the access modifiers for each account to be private.
Since the entire point of the facade design pattern is to hide complexity,
we use the information hiding design principle to prevent
all client classes from seeing the account objects and how these accounts behave.
Step four. Use the facade class to access the subsystem.
Client classes can access the functionalities of
the different accounts through the methods of the BankService class.
The BankService class will tell the client what type
of actions it will allow the client to call upon,
and then will delegate that action to the appropriate account objects.
Now that we have our facade in place,
our client class can access its accounts through the BankService.
Your customer class does not need to worry about creating and managing its own accounts.
The customer simply needs to know about the BankService and
the set of behaviors the BankService is capable of performing.
We have effectively hidden the complexity of account management from the customer using
the BankService facade class.
The facade design pattern is similar to other design patterns in
that it uses encapsulation to hide the details of some part of our system.
It can be easy to get these design patterns mixed up,
so let's summarize what characterizes the facade design pattern.
The facade design pattern is a means to hide the complexity of
a subsystem by encapsulating it behind a unifying wrapper called a facade class;
removes the need for client classes to manage a subsystem on their own,
resulting in less coupling between the subsystem and the client classes;
handles instantiation and redirection of
tasks to the appropriate class within the subsystem;
provides client classes with a simplified interface for the subsystem;
acts simply as a point of entry to a subsystem and
does not add more functionality to the subsystem.
The facade design pattern is a way to provide
client classes with an easier means of interacting with the parts of your system.
Complex subsystems can be difficult to use and navigate.
By providing a simpler interface through a facade,
client classes will have an easier time successfully using your software.