Facade Design Pattern
Saji Kuttan
Senior Software Engineer @HCL TECH | Ex-Infoscion | Building Secure and Scalable Software's | Full Stack Developer
The Facade Design Pattern is a structural design pattern that provides a simplified interface to a complex subsystem of classes, making it easier to interact with them. Instead of interacting with multiple classes directly, you use the facade to reduce the complexity. This pattern is particularly useful when dealing with large systems with many interacting classes or libraries.
Example of Facade Design Pattern: Home Theater System
Imagine you have a home theater system with multiple devices like a TV, Sound System, Blu-ray Player, and Lights. To watch a movie, you have to turn on and configure each device individually, which can be complex. By implementing a HomeTheaterFacade, you can simplify this process with just a single method, like watchMovie(), to control all the subsystems.
Key Components:
1. Subsystem Classes: These are the individual complex classes that the facade interacts with (e.g., TV, SoundSystem, Blu-ray Player).
2. Facade Class: The simplified interface that provides easy access to complex subsystems (e.g., HomeTheaterFacade).
Example:
Step 1: Create the Subsystem Classes
```java
// TV Subsystem
public class TV {
public void turnOn() {
System.out.println("TV is turned on.");
}
public void setInputChannel(String channel) {
System.out.println("TV is set to " + channel + " input.");
}
public void turnOff() {
System.out.println("TV is turned off.");
}
}
// Sound System Subsystem
public class SoundSystem {
public void turnOn() {
System.out.println("Sound system is turned on.");
}
public void setVolume(int level) {
System.out.println("Sound system volume set to " + level);
}
public void turnOff() {
System.out.println("Sound system is turned off.");
}
}
// Blu-ray Player Subsystem
public class BluRayPlayer {
public void turnOn() {
System.out.println("Blu-ray player is turned on.");
}
public void playMovie(String movie) {
System.out.println("Playing movie: " + movie);
}
public void turnOff() {
System.out.println("Blu-ray player is turned off.");
}
}
// Lights Subsystem
public class Lights {
public void dimLights() {
System.out.println("Lights are dimmed.");
}
public void turnOff() {
System.out.println("Lights are turned off.");
}
}
```
Step 2: Create the Facade Class (HomeTheaterFacade)
```java
// The Facade Class
public class HomeTheaterFacade {
private TV tv;
private SoundSystem soundSystem;
private BluRayPlayer bluRayPlayer;
private Lights lights;
public HomeTheaterFacade(TV tv, SoundSystem soundSystem, BluRayPlayer bluRayPlayer, Lights lights) {
this.tv = tv;
this.soundSystem = soundSystem;
this.bluRayPlayer = bluRayPlayer;
this.lights = lights;
}
领英推荐
public void watchMovie(String movie) {
System.out.println("Getting ready to watch a movie...");
lights.dimLights();
tv.turnOn();
tv.setInputChannel("HDMI");
soundSystem.turnOn();
soundSystem.setVolume(20);
bluRayPlayer.turnOn();
bluRayPlayer.playMovie(movie);
}
public void endMovie() {
System.out.println("Shutting down the home theater...");
bluRayPlayer.turnOff();
soundSystem.turnOff();
tv.turnOff();
lights.turnOff();
}
}
```
Step 3: Demonstrate the Facade Design Pattern
```java
public class Main {
public static void main(String[] args) {
// Subsystems
TV tv = new TV();
SoundSystem soundSystem = new SoundSystem();
BluRayPlayer bluRayPlayer = new BluRayPlayer();
Lights lights = new Lights();
// Facade
HomeTheaterFacade homeTheater = new HomeTheaterFacade(tv, soundSystem, bluRayPlayer, lights);
// Watch a movie
homeTheater.watchMovie("Inception");
System.out.println();
// End the movie
homeTheater.endMovie();
}
}
```
Output:
```
Getting ready to watch a movie...
Lights are dimmed.
TV is turned on.
TV is set to HDMI input.
Sound system is turned on.
Sound system volume set to 20.
Blu-ray player is turned on.
Playing movie: Inception
Shutting down the home theater...
Blu-ray player is turned off.
Sound system is turned off.
TV is turned off.
Lights are turned off.
```
Explanation:
1. Subsystems (TV, SoundSystem, BluRayPlayer, Lights): These are individual classes that handle specific aspects of the home theater system.
2. Facade (HomeTheaterFacade): This class simplifies the interaction with the complex subsystems. Instead of dealing with each component separately, the user can call methods like watchMovie() or endMovie().
Workflow:
- To watch a movie, instead of manually turning on the TV, adjusting the sound system, playing the movie, and dimming the lights, the HomeTheaterFacade simplifies this into one method call: watchMovie().
- Similarly, when you finish watching, the endMovie() method turns everything off.
Advantages:
- Simplified Interface: The facade provides a unified, easy-to-use interface, masking the complexities of the underlying subsystems.
- Decoupling: The client code interacts with the facade rather than multiple subsystems directly, reducing the dependency on the underlying details.
- Flexibility: You can change or update the internal components without affecting the client, as the facade shields the complexity.
Use Cases:
- Complex Systems: When you have systems with multiple subsystems or libraries, and you want to provide a more straightforward interface (e.g., home automation systems, graphics rendering engines).
- Legacy Systems: When integrating a legacy system that has many interfaces, you can create a facade to simplify interaction with modern code.
Conclusion:
The Facade Design Pattern is a great tool to simplify interactions with complex subsystems. In our Home Theater System example, the facade hides the complexity of controlling individual components and provides a single point of interaction, making it easier for the client to use.
#SoftwareDesign #StatefulPattern #Architecture #DesignPatterns #Developers #ProgrammingTips #facadedesignpattern #JAVA #C #CPP #JAVASCRIPT #Python