
Structural Design Pattern - Facade
Author - Abdul Rahman (Bhai)
Design Pattern
13 Articles
Table of Contents
What we gonna do?
In this article, let's learn about Facade Design Pattern in .NET.
The Facade pattern, a stalwart from the Gang of Four design patterns, serves as a unified interface to a subsystem, simplifying its usage. Imagine a world where operating an entertainment system involves intricate steps—enter the Facade pattern. In this blog, we'll explore its real-life application through a entertainment service, delve into its structure, uncover its use cases, weigh its advantages and disadvantages, touch upon related patterns, and conclude with a concise summary.
Why we gonna do?
Without a Facade, every client that wants to start or stop the entertainment system must interact with each subsystem class directly—calling TurnOn on the DvdPlayer, then on the SoundSystem, then on the Projector—in the right sequence and with full knowledge of each component's API. This orchestration logic ends up scattered across every part of the codebase that needs to control the system.
As the subsystem grows—new components are added, existing classes change their interfaces, or startup sequences become order-dependent—every call site must be updated in lockstep. The tight coupling between client code and subsystem internals makes the code fragile, difficult to test, and expensive to maintain.
The Facade pattern solves this by introducing a single EntertainmentFacade class that encapsulates all subsystem interactions. Clients call one high-level method such as TurnOnEntertainmentSystem and remain completely decoupled from the individual components beneath it. Changes to the subsystem need only be reflected in the facade, leaving client code untouched.
How we gonna do?
Structure
The Facade pattern, encapsulated in a facade (like our "entertainment facade"), orchestrates subsystem classes DvdPlayer, Sound System, and Projector service. The facade shields clients from the complexities, acting as a gateway to the subsystem, promoting an organized and manageable structure.
// Subsystem classes
class DvdPlayer
{
public void TurnOn()
{
Console.WriteLine("DVD Player is ON");
}
public void TurnOff()
{
Console.WriteLine("DVD Player is OFF");
}
}
class SoundSystem
{
public void TurnOn()
{
Console.WriteLine("Sound System is ON");
}
public void TurnOff()
{
Console.WriteLine("Sound System is OFF");
}
}
class Projector
{
public void TurnOn()
{
Console.WriteLine("Projector is ON");
}
public void TurnOff()
{
Console.WriteLine("Projector is OFF");
}
}
// Facade class
class EntertainmentFacade
{
private DvdPlayer _dvdPlayer;
private SoundSystem _soundSystem;
private Projector _projector;
public EntertainmentFacade()
{
_dvdPlayer = new DvdPlayer();
_soundSystem = new SoundSystem();
_projector = new Projector();
}
public void TurnOnEntertainmentSystem()
{
_dvdPlayer.TurnOn();
_soundSystem.TurnOn();
_projector.TurnOn();
}
public void TurnOffEntertainmentSystem()
{
_dvdPlayer.TurnOff();
_soundSystem.TurnOff();
_projector.TurnOff();
}
}
// Client code
class Program
{
static void Main()
{
EntertainmentFacade entertainmentFacade = new EntertainmentFacade();
// Turn on the entire entertainment system
entertainmentFacade.TurnOnEntertainmentSystem();
// Simulate some movie-watching...
// Turn off the entire entertainment system
entertainmentFacade.TurnOffEntertainmentSystem();
}
}
In the above code snippet, Subsystem Classes DvdPlayer, SoundSystem, and Projector represent individual components of the home entertainment system. Facade Class EntertainmentFacade class acts as a facade, providing simplified methods TurnOnEntertainmentSystem and TurnOffEntertainmentSystem. These methods internally manage the individual components, abstracting away their complexities. Client Code Program creates an instance of EntertainmentFacade and uses its methods to turn on and off the entire entertainment system. The client is shielded from the details of interacting with each subsystem separately. This example demonstrates how the Facade pattern can simplify the usage of a complex system, making it easy for clients to perform common tasks without dealing with the intricacies of individual components.
Use Cases
- Simplifying Complexity - When dealing with intricate subsystems, the Facade pattern offers a clean, high-level interface, shielding clients from the nitty-gritty details.
- Decoupling Dependencies - In scenarios with numerous dependencies between clients and implementation classes, introducing a facade breaks the tight coupling, fostering a more flexible design.
- Integration with Legacy Systems - Facades prove invaluable when bridging new and legacy systems, abstracting away the intricacies of dealing with legacy code.
- Content Management Systems - Streamlining operations in systems handling diverse content types, such as articles, images, and videos.
- Multimedia Playback - Abstracting the complexities of supporting various media formats and providing a unified playback control interface.
- Payment Processing in E-commerce - Facilitating a unified interface for processing payments, irrespective of the underlying payment gateways.
Advantages
- Reduced Client Complexity - Clients interact with a simplified facade, oblivious to the intricate workings of the subsystem.
- Weak Coupling - Facades promote loose coupling between clients and subsystems, allowing subsystem components to evolve independently.
- Open-Closed Principle - Clients can easily adapt to changes in subsystem components without modification, adhering to the open-closed principle.
Disadvantages
Potential Overhead - Introducing facades might add a layer, potentially introducing overhead, especially in simpler systems.
Related Patterns
- Abstract Factory pattern
- Mediator pattern
- Adapter pattern
Summary
In essence, the Facade pattern simplifies the usage of complex subsystems, providing a clean and unified interface. It excels in scenarios where reducing client complexity, decoupling dependencies, and integrating with legacy systems are paramount. As we wrap up this exploration, keep in mind that the Facade pattern, while powerful, finds its strength in its judicious application alongside other complementary design patterns.