In this episode, we look at the facade pattern. This is one we have likely run into when we have dealt with complex systems. In general, a facade pattern is an interface that summarizes a group of interfaces or objects in a functional group. Without further ado, let’s take a look at this simplifying pattern.
The Facade Pattern Defined
As always, we will start with the “Gang of Four” intent to set the stage for our discussion.
“Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.”
That last bit of the intent is the most import. They saved the best for last. The goal of the decorator pattern is to provide an interface that makes a complex system easier to use. It provides us with another layer of abstraction when building complex systems. There are a lot of API examples that fall into this category. There are the core API calls and then there are underlying (often undocumented) interfaces and classes that can be called directly in some cases.
Applying The Pattern
A facade is much like a roadmap or a menu for other functions. It is important to note that this is a one-way street. The facade can call its group classes/objects but they do not know if it even exists. It may also be thought of as a controller in a way. This pattern knows how the sub-objects should be called or interact. Thus, it can be used to reduce the steps a developer calls or that need to be exposed to the user code.
Therefore, large systems will be the ones where a facade is most useful. A case where you only have a few objects will not be served by this pattern and will just be another level of abstraction without benefit. A good rule-of-thumb is what the facade methods do. If it is basically a one-to-one pass through then the facade serves no purpose. Typically, a facade will hide multiple calls per method on the top-level class or interface.
Java, PHP, C#, etc.
Finally, a facade is almost always a class. An interface will not be able to roll-up functionality as is required of this pattern. If you have a language that allows implementation within an interface then you could go that route for a facade. However, that approach implies you are not building a proper facade. Each method on a facade should translate to executing steps across multiple other objects.