The Facade Design Pattern is a structural pattern that provides a simplified interface to a complex subsystem. It hides the complexity of the subsystem and makes it easier to use. The pattern involves creating a facade class that delegates requests to the appropriate components of the subsystem.
Components of the Facade Design Pattern:
- Facade: The class that provides a simplified interface to the complex subsystem.
- Subsystem Classes: The classes that make up the complex subsystem. They handle the actual operations and functionality.
Simple Example:
Let’s create a simple example where we have a home theater system with several components. We will use the Facade Pattern to provide a simplified interface for turning on and off the home theater system.
1. Subsystem Classes:
// Subsystem class 1
class Amplifier {
public void on() {
System.out.println("Amplifier is on");
}
public void off() {
System.out.println("Amplifier is off");
}
}
// Subsystem class 2
class DVDPlayer {
public void on() {
System.out.println("DVD Player is on");
}
public void off() {
System.out.println("DVD Player is off");
}
public void play(String movie) {
System.out.println("Playing movie: " + movie);
}
}
// Subsystem class 3
class Projector {
public void on() {
System.out.println("Projector is on");
}
public void off() {
System.out.println("Projector is off");
}
}
// Subsystem class 4
class Screen {
public void down() {
System.out.println("Screen is down");
}
public void up() {
System.out.println("Screen is up");
}
}
// Subsystem class 5
class Lights {
public void dim(int level) {
System.out.println("Lights dimmed to " + level + "%");
}
}
2. Facade Class:
// Facade class
class HomeTheaterFacade {
private Amplifier amplifier;
private DVDPlayer dvdPlayer;
private Projector projector;
private Screen screen;
private Lights lights;
public HomeTheaterFacade(Amplifier amplifier, DVDPlayer dvdPlayer, Projector projector, Screen screen, Lights lights) {
this.amplifier = amplifier;
this.dvdPlayer = dvdPlayer;
this.projector = projector;
this.screen = screen;
this.lights = lights;
}
public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
lights.dim(10);
screen.down();
projector.on();
amplifier.on();
dvdPlayer.on();
dvdPlayer.play(movie);
}
public void endMovie() {
System.out.println("Shutting down movie theater...");
lights.dim(100);
screen.up();
projector.off();
dvdPlayer.off();
amplifier.off();
}
}
3. Client Code:
public class FacadePatternDemo {
public static void main(String[] args) {
Amplifier amplifier = new Amplifier();
DVDPlayer dvdPlayer = new DVDPlayer();
Projector projector = new Projector();
Screen screen = new Screen();
Lights lights = new Lights();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amplifier, dvdPlayer, projector, screen, lights);
homeTheater.watchMovie("Inception");
homeTheater.endMovie();
}
}
Explanation:
- Subsystem Classes: These classes (
Amplifier
,DVDPlayer
,Projector
,Screen
,Lights
) represent the complex components of the home theater system. - Facade Class:
HomeTheaterFacade
provides a simplified interface with methodswatchMovie
andendMovie
to manage the subsystem components. It coordinates between the components to handle the required operations. - Client Code: Demonstrates how to use the
HomeTheaterFacade
to set up and shut down the home theater system without interacting with each component directly.
Benefits of the Facade Design Pattern:
- Simplified Interface: Provides a single, unified interface to a set of interfaces in a subsystem, making it easier to use.
- Decoupling: Reduces the dependency between the client code and the complex subsystem.
- Ease of Use: Makes it easier to interact with complex systems by providing high-level methods.
Use Cases of the Facade Design Pattern:
- Complex Libraries: Simplifying interactions with complex libraries or frameworks.
- System Integration: Providing a unified interface for interacting with multiple subsystems in a software application.
- Legacy Code: Wrapping legacy code with a facade to simplify its use in modern applications.
The Facade Pattern is particularly useful when you need to provide a simpler, higher-level interface to a complex subsystem or set of classes.