Facade Pattern
The Facade is a structural design pattern that provides a simplified interface to a complex subsystem, hiding its intricacies behind a single entry point. It promotes loose coupling by letting clients interact with a high-level facade rather than multiple subsystem classes.
Key Principles
- Simplify Complexity: Wraps a library/API with a clean, user-friendly interface.
- Layer of Abstraction: Clients don't need to know subsystem details.
- Single Responsibility: Facade handles coordination/orchestration.
Structure
- Subsystem: Group of classes with complex interactions.
- Facade: Single class that knows how to use the subsystem; exposes simple methods.
- Client: Interacts only with Facade.
Python Example: Home Theater System Facade
# Subsystem Classes (Complex)
class Amplifier:
def on(self):
print("Amplifier: ON")
def set_dvd(self, dvd_player):
print("Amplifier: Setting DVD player")
def set_volume(self, level):
print(f"Amplifier: Volume {level}")
class DvdPlayer:
def on(self):
print("DVD Player: ON")
def play(self, movie):
print(f"DVD Player: Playing {movie}")
class Projector:
def on(self):
print("Projector: ON")
def set_input(self, input_type):
print(f"Projector: Input {input_type}")
def wide_screen_mode(self):
print("Projector: Wide screen mode")
class TheaterLights:
def dim(self, level):
print(f"Theater Lights: Dimmed to {level}%")
# Facade (Simplified Interface)
class HomeTheaterFacade:
def __init__(self, amp, dvd, projector, lights):
self.amp = amp
self.dvd = dvd
self.projector = projector
self.lights = lights
def watch_movie(self, movie):
print("=== Starting Movie ===")
self.lights.dim(10)
self.projector.on()
self.projector.set_input("DVD")
self.projector.wide_screen_mode()
self.amp.on()
self.amp.set_dvd(self.dvd)
self.amp.set_volume(5)
self.dvd.on()
self.dvd.play(movie)
print("=== Enjoy the show! ===\n")
def end_movie(self):
print("=== Ending Movie ===")
self.dvd.stop()
self.amp.off()
self.projector.off()
self.lights.on()
print("=== Lights up! ===\n")
# Usage (Client Code)
if __name__ == "__main__":
amp = Amplifier()
dvd = DvdPlayer()
projector = Projector()
lights = TheaterLights()
theater = HomeTheaterFacade(amp, dvd, projector, lights)
# Client uses simple facade
theater.watch_movie("Avengers")
theater.end_movie()
Output:
=== Starting Movie ===
Theater Lights: Dimmed to 10%
Projector: ON
Projector: Input DVD
Projector: Wide screen mode
Amplifier: ON
Amplifier: Setting DVD player
Amplifier: Volume 5
DVD Player: ON
DVD Player: Playing Avengers
=== Enjoy the show! ===
=== Ending Movie ===
DVD Player: Stopped
Amplifier: OFF
Projector: OFF
Theater Lights: ON
=== Lights up! ===
When to Use Facade
- Complex Subsystems: Wrap libraries with many classes (e.g., database APIs).
- API Simplification: Provide high-level methods for beginners.
- Avoid: When subsystem is simple (over-abstraction).
Summary: Facade offers a unified, simple interface to a complex subsystem, reducing client complexity while maintaining encapsulation.