This week we’ll continue our exploration of design patterns and look at another structural pattern, the Façade pattern.
The Façade Pattern
The Gang of Four book defines the Façade pattern as follows:
“Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.”
Occasionally we need to call a series of methods from a number of classes in order to execute a particular task. The Façade pattern creates a single, separate object that simplifies the execution of these steps. It provides a single, simple interface to a larger, more complex subsystem. By doing this, it adds a layer of abstraction to the subsystem.
The Façade gives a simple view of the subsystem that is sufficiently useful for most programmers. By “glueing” the classes in the subsystem together, the Façade makes coding easier. If a programmer needs more customisability, then they can use the low level classes. The functionality of these low-level classes isn’t hidden from the programmers who need it.
Structure of the Facade Pattern
The Façade design pattern is one of the easiest to understand and implement. It consists of a single class that provides the simplified interface to the existing subsystem. The methods of the class delegate the work to lower-level classes in the subsystem. In many ways, it is more procedural than object-oriented, because it doesn’t use interfaces, inheritance or polymorphism.
Façade Examples from the Java API
A good example of the Façade design pattern in the Java API is the Swing JOptionPane
class. The JOptionPane
simplifies the task of creating a standard look and feel dialog box. A programmer doesn’t need to know the detailed low-level steps to created a dialog box. The JOptionPane
provides methods such as showConfirmDialog()
, showInputDialog()
and showMessageDialog()
. These are simple, one-line calls to create standard dialog boxes. The low-level interfaces are still there if a programmer wants to create a customised dialog box.
JOptionPane
doesn’t do any of the hard work of creating dialog boxes; it just delegates requests to other Swing classes. Programmers are free to ignore the JOptionPane
, and create dialog boxes directly using these lower-level classes. However, using a JOptionPane
makes it easier to create dialog boxes with a standard look and feel.
Other examples from the standard Java APIs include:
javax.faces.context.FacesContext
uses theLifeCycle
,ViewHandler
,NavigationHandler
and other classes internally without the client needing to know how to use each individual class.javax.faces.context.ExternalContext
internally usesServletContext
,HttpSession
,HttpServletRequest
,HttpServletResponse
, etc.
Façade Pattern: Example Code
Back in our first person shooter game, we need to be able to calculate the damage done to players and monsters during a battle, and if and when the combatants will die from their wounds.
For this we would need to access a number of different classes and do a series of related calculations. For each combatant (it could be a player, a monster, a vehicle, etc.) we would need to:
- Check the current health of the combatant.
- Check the level of armour used.
- Check the type of weapon used, and how many hits were taken.
- Check the distance between combatants.
- Check the accuracy of the hits/shots.
Once we had accessed all this information for all the different classes, we would need to run a series of calculations to determine the outcome of any interaction. Clearly this is a fairly complex set of steps to be run in a particular order.
A good solution for this problem would be to create a single class (with possibly a single method) that would simplify the interaction between the relevant classes. This is the Façade design pattern.
Let’s create a DamageCalculator
class with a method that calls the correct methods of all the involved objects.
public class DamageCalculator { public int calculateHealth(Combatant attacker, Combatant target) { // cumulative health count int health = 0; // Check the current health of the target. health += target.getCurrentHealth(); health += target.getMedicalKit().healingPower(); // Check the level of armour used by the target. health += target.getArmourLevel(); // Check the damage the attacker's weapon can inflict. // Multiply by how many hits were taken by the target // and the accuracy of the attacker. double damage = target.getWeapon().getDamageAbility() * target.getWeapon().getShotsFired() * attacker.getAccuracy(); // Check the distance between combatants. double distance = calculateDistance(attacker.getPosition(), target.getPosition()); // Do extra calculations using health, damage and distance // more code... return health; } }
If we look at the calculateDamage()
method, we can see that there’s a lot of low-level code that must be called in a specific order to calculate the damage done during a fight. This is a fairly complex process, and if a programmer forgot to invoke the steps in the correct order each time, the game would be riddled with hard to find bugs.
Defining a façade class solves this problem. Client programs only need to call the calculateDamage()
method, without having to know how to use all the individual classes and what methods to call when. If we need to calculate the combatant’s damage in any specific way, then we can still call the individual methods without using the façade class.
Related Patterns
Facade defines a new interface, whereas Adapter uses an old interface. Adapter makes two existing interfaces work together as opposed to defining an entirely new one.
Adapter and Facade are both wrappers, but they are different kinds of wrappers. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to adapt one interface to another interface. Facade usually wraps multiple objects and Adapter wraps a single object. However, Facade could be the front-end of a single complex object and Adapter could wrap several legacy objects.
Usually only one Façade class per subsystem is required, so they are often coded as singletons.
What’s Next?
In the weeks ahead, we’ll continue examining some of the more useful design patterns. Stay tuned!