We're working on a substantial update for the whole design patterns section that should be ready by the end of September. Until then, please sorry for all embarrassing typos and errors you might encounter here and there.
Facade is a structural design pattern that lets you provide a simplified interface to a complex system of classes, library or framework.
Imagine the code that has to work with a large set of objects of some complex library or framework. You have to manually initialize all these objects, keep track of the dependencies, correct order and so on.
In the end, the business logic of your classes becomes tightly coupled to the implementation details of third party library. Such code is pretty hard to comprehend and maintain.
The facade is a class that provides a simple interface to a complex subsystem containing dozens of classes. The facade may have limited functionality in comparison to working with subsystem directly. However, it includes only those features that clients really care about.
Facade is handy when you use a sophisticated library with a lot of moving parts, but you need only a fraction of its functionality.
For instance, an app that uploads short videos with cats to the Youtube could use a professional video conversion library. But all that it really needs is a class with a single method
encode(filename, format). After creating such class, you get your first facade.
Placing orders by phone
When you call a shop to place a phone order, an operator is your facade to all services and departments of the shop. He or she provides a simple interface to the ordering system, payments, and delivery services.
Facade provides convenient access to a particular part of the subsystem's functionality. It knows where to direct the client request and how to prepare all the moving parts.
Additional facades can be created to divide responsibilities and prevent growing an original facade into yet another complex structure. Additional facades can be used either by Clients or other Facades.
Complex subsystem contains dozens of classes. To make them do something meaningful, you have to know their implementation details, the initialization order and lots of other things.
Note that subsystem classes are not aware of the Facade's existence and work with each other directly.
Client uses Facade instead of calling the Subsystem objects directly.
In this examples, the Facade simplifies interaction with a complex video conversion framework.
The Facade is a single class with a single public method that handles all the complexity of configuring the right classes of the framework and retrieving result in a correct format.
This way the Facade pattern shields client code from the complexity, keeps it clean and lean.
When you need to have a simple but limited interface to a complex subsystem.
Often subsystems get more complex over time. Even applying design patterns often leads to creating more classes. The subsystem may become more flexible and easier to reuse in different contexts, but the amount of boilerplate code it requires also grows. The Facade attempts to fix it by providing access to a fraction of a subsystem that fits most client needs.
When you want to structure a subsystem into layers.
Create facades to define entry points to each level of a subsystem. If multiple subsystems depend on each other, you can limit the coupling by requiring subsystems to communicate only through facades.
How to Implement
Check whether it is possible to simplify the interface of communication with a complex subsystem.
You are on the right track if this interface will make client free of subsystem dependency.
Create a facade class and describe this interface in it. It has to direct client calls to the appropriate objects of the subsystem. Facade should take care of correct subsystem initialization. Usually, this code lives inside the facade constructor. Lazy initialization may also be useful.
You will get a full benefit if client code only works with the facade. In this case, the client will be protected from all changes in the subsystem code. For example, when a library's code gets updated, you will only need to fix a facade.
If the facade becomes monstrous, think of extracting new refined facades.
Pros and Cons
- Isolates clients from subsystem components.
- Minimizes coupling between client code and subsystem.
- Facade risks becoming a god object, coupled to all application classes.
Relations with Other Patterns
Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communications between colleague objects. It routinely "adds value", and it is known/referenced by the colleague objects. In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes.
Facade is similar to Proxy in that it buffers a complex entity and also initializes it. Unlike the Facade, the Proxy pattern has the same interface as its service object, which makes them interchangeable.