The Facade Pattern provides a unified interface to a set of interfaces in a subsystem.
Facade defines a higher-level interface that makes the subsystem easier to use.
The Facade Pattern is used when you need to simplify and unify a large interface or complex set of interfaces.
It alters an interface to simplify it and thereby hides all the complexity of one or more classes behind a clean facade,
hence its name. A facade decouples a client from a complex subsystem and to implement it we compose the facade with its
subsystem and use delegation to perform the work of the facade.
For a complex subsystem it can be helpful to implement more than one facade.
Thereby we try to keep sybsystems adhering to the Principle of Least Knowledge as well.
If this gets too complex and too many friends are intermingling, we can introduce additional facades to form layers of subsystems.
The components of the complex subsystem can be upgraded/changed without affecting the client.
The client usually has only one friend: the Facade class,
which follows the Principle of Least Knowledge:
In OO programming, having only one friend is a good thing.
This pattern is similar to the Adapter Pattern and the Decorator Pattern.
An adapter wraps an object to change its interface, a decorator wraps an object to add new behaviors and responsibilities,
and a facade “wraps” a set of objects to unify and simplify.
The following example shows a home theater with multiple classes, acting as devices of the home theater that interact with each other and are connected to the Amplifier that is defined later:
For example, we have a Tuner to listen to the radio that can set the mode (AM, FM) and the frequency:
To watch movies a DvdPlayer is connected to the Amplifier:
Another device that is connected to the Amplifier is the CdPlayer:
Each of the devices defined so far are connected with the Amplifiler:
To actually watch a movie we need a Projector and a Screen that can be moved up() or down():
Here is the definition of the Screen class:
To watch a movie we also want to dim the lights:
Finally to enjoy the movie even more, we have a popcorn popper:
It is possible to interact with those subsystems directly without using a Facade.
This means that we get low-level access to the complex subsystem.
However, for tasks such as watching a movie or listening to the readio,
the Facade Pattern provides a unified and simple interface with the following HomeTheaterFacade class,
that allows watching a movie with a single method watchMovie(String movie) and shut everything down afterwards in the correct order with endMovie():
To watch a movie we could use the components of the subsystem directly (hard way) by doing the following steps:
Turn on the popcorn popper
Start the popper popping
Dim the lights
Put the screen down
Turn the projector on
Set the projector input to DVD
Putth eprojector on wide-screen mode
Turn the sound amplifier on
Set the amplifier to DVD input
Set the amplifier to surround sound
Set the amplifier volume to medium (5)
Turn the DVD palyer on
Start the DVD player playing
We would have to create the required devices ourselfs and then call each of its method in the correct order:
As we can see, this involves six different classes.
Using the HomeTheaterFacade gives us a single method to achieve the same: