Facade pattern is structural design pattern, that hides complexity of the system components, wrapping them into one class with well designed, simplified interface.
When I first read Design Patterns [GoF] I was charmed by a lot of patterns introduced by authors. Some of them I was known earlier (like Abstract Factory or Observer), but most of them were new concepts for me. One of the easiest pattern to assimilate and use was Facade pattern which I want to discuss.
By definition Facade pattern provides simple interface to complex subsystem. By a complex subsystem I mean some related classes and their processes. They can be our program classes (I pattern adoption), or legacy libraries (II pattern adoption).
According to Holub on Patterns [Holub] :
Subsystems, especially older ones, are masses of spaghetti code. When two subsystems must interact, they often make calls directly into each other, and these myriad tendrils of connectivity are a maintenance nightmare. The subsystems become very delicate since making seemingly insignificant changes in a single subsystem can affect the entire program. Facade addresses the problem by forcing programmers to use a subsystem indirectly through a welldefined single point of access, thereby shielding the programmers from the complexity of the code on the other side of the facade.
Provide simplified interface to complex subsystem components
Have you ever write some method in some client class, which had to know too much about components it uses? This method had to know about components methods, coordination of execution of that methods, and final result of that process realization was not final goal of that method, but only part of it?
This indicates that process of the components should be defined in another class, and introduced by simple, well designed interface. This interface is one and only entrypoint to the subsystem from the client point of view.
This UML diagrams shows the concept:
Before facade class was created, Client 1 and Client 2 were using more than one related classes in complex subsystem. Let’s say that clients was controllers in presentation layer, and complex subsystem was real, business logic in service layer.
This can lead to bad consequences, expecially if system is big and a lot of clients has a direct access to that related complex subsystem classes.
First of all, if any related class of the subsystem change its public interface (it can be only one method), then all clients, which call that method must be changed, recompiled and retested. If we have only one or two clients in one place it coultn’t be effort, but what if we have 100 clients in disturbed locations? Refactoring, recompiling, redeploying and retesting could be hell.
Second of all, if complex subsystem classes are related, they probably must be coordinated, to do some job and give some result. It means that there is need to execute more than one method in more than one subsystem class, to get some output, which client is interested in. This starting to pretend like code smell. Why would the client need to know about complex task process to get the needed data? What if we have to use the same process in more than one client?
Consider real world scenario. You (client) are going to withdraw money from ATM machine (complex subsystem). Do you have to know how to and in which order use some elements inside like Cash Deposit Unit, Card Reader, Cash Reciever or Bill Reader to get your money, check your account info, or print some bill? No, because all this related components processes, are hidden behind ATM Machine Facade. You would not even seen that components, because they are hidden from you. You probably don’t even know what components are inside ATM, and you don’t care about it. This knowledge is not required to handle with ATM. And this knowledge is not required from you, because ATM Machine Facade has well designed interface! All you have to do is use simple terminal, push your card, enter PIN number and mystery magic happens! Now, what if one day Bank (or some other ATM Machine provider) will want to change some components inside ATM Machine to faster, more optimized ones? Well this is simple, since none of the clients knows about components inside. They don’t need to learn how to deal with new components, they can still deal with ATM Machine interface.
I know this may be obviousness and intuitive to some readers, but that’s why this pattern is so simple and easy to start.
Lets see some real code
Ok, we can skip real world examples and dive into real code. This is example of my home budget app, which I’ve developed half year ago. This was desktop app, and it was using JavaFX. This application has a form to create new home budget period. And save budget period method in the Controller looks like this:
This method gets data from form fields into PeriodFormDto, then saves period and prints success message. If period is not valid, then ValidatorException is being thrown and error messages appear on user screen. Can you spot Facade pattern object?
Of course, Facade object is PeriodService which is responsible for do some logic with given PeriodFormDto. This object is Facade, which simplify save period process.
Notice that from client point of view (Controller), it does not matter what is implementation of PeriodService interface and what components are processing given task. All the client need to know is the interface, which tells that savePeriod method creates new period if data is valid, and throws exception if data is invalid.
This gives us a lot of flexibility, because client is unaware of complex subsystem, and this gives you a opportunity to change subsystem components without client compile error.
We have to remember that Facade interface should be one and only entrypoint to our subsystem classes. Subsystem components should be not accessible from clients point of view. Subsystem components should not be public. What is purpose of Facade interface if clients still can have direct access to subsystem classes? You have to design reasonably and hide what you do not want to show.
Second usage of Facade pattern
Facade pattern is also great pattern to work with legacy code. This can be old system with badlly written components, or some libraries that we want to or have to use in our system. I’ll focus on the second ones.
Libraries for programmers must be very flexible to find the widest usage. However, when we want to use some library component in our system, usually we only need some of available functionality. Moreover, some functionality is undesirable, but we still have to handle with it. This is example from my project, PeriodRepository. I use Spring Data JPA library to generate Repositories for my app. Spring Data JPA allows you to write new data access methods, but still forces you to deal with base interface public methods.
This are the public, contract methods from PeriodRepository. As you can see, only three methods are really defined in my interface, another ones comes from interface parent, SpringDataJPA. Now, I want to show my clients only PeriodRepository methods, and one method from JpaRepository – save(S entity). How to handle with that?
A bad idea is to use this PeriodRepository interface directly, and count on that some of our collagues, won’t use unwanted methods in the future.
A better idea is to provide Facade pattern class, which will deal with legacy API and expose methods, that we actually want to expose. Let’s create simple one:
This time Facade only wraps PeriodRepository, and delegating method executions to it. From this point of time we should use only PeriodRepositoryFacade instead of PeriodRepository in our clients. Moreover, we should make PeriodRepository not accessible for clients. Let’s look how contract of PeriodRepositoryFacade looks like to clients:
As we can see, unwanted legacy methods from JpaRepository has gone, and we can use PeriodRepositoryFacade according to specifications without any fear that unwanted legacy code will be used in the future.
Facade pattern is one of the simpliest, powerful, and most used design patterns. It enforces to follow with encapsulation, data and processes hiding, and simplify clients code. It also helps to deal with legacy API, badly written API, overly complex API.