What is the Facade Pattern?
The Facade Pattern is a structural design pattern that provides a simplified interface to a complex subsystem. It hides the complexity of multiple interacting components behind a single, clean, high-level interface. The subsystem classes still work as before — the facade is just a convenience layer on top.
Explanation
Real-World Analogy
- Think of a hotel concierge 🏨:
- You tell the concierge: “Book me a restaurant, arrange a taxi, and get me theater tickets.”
- You don’t call the restaurant, the taxi company, and the theater separately.
- The concierge (facade) coordinates all of them for you.
- Behind the scenes: 3+ separate systems. From your perspective: one interface.
Facade vs Adapter
| Adapter Pattern | Facade Pattern | |
|---|---|---|
| Purpose | Convert one interface to another | Simplify many interfaces into one |
| Changes interface | Yes | Yes, but creates new simpler one |
| Works with | One class | Many classes / a subsystem |
| Intent | Compatibility | Simplicity |
UML Structure
classDiagram class Facade { -subsystem1: SubA -subsystem2: SubB -subsystem3: SubC +simpleOperation() } class SubsystemA { +operationA1() +operationA2() } class SubsystemB { +operationB1() +operationB2() } class SubsystemC { +operationC1() } class Client { +run() } Client --> Facade : uses Facade --> SubsystemA Facade --> SubsystemB Facade --> SubsystemC
Implementation
-
Home Theater Facade — turn on the home theater system with one call instead of operating 5 separate components. Python · Cpp · Java · Java Script · CSharp
Languages:
# ─── Python ──────────────────────────────────────────────────────────
# ── Complex Subsystem Classes ─────────────────────────────────────────
class Amplifier:
def on(self) -> None: print("Amplifier: ON")
def off(self) -> None: print("Amplifier: OFF")
def set_volume(self, v) -> None: print(f"Amplifier: Volume → {v}")
def set_surround(self) -> None: print("Amplifier: Surround sound ON")
class DVDPlayer:
def on(self) -> None: print("DVD Player: ON")
def off(self) -> None: print("DVD Player: OFF")
def play(self, movie: str)-> None: print(f"DVD Player: Playing '{movie}'")
def stop(self) -> None: print("DVD Player: Stopped")
class Projector:
def on(self) -> None: print("Projector: ON")
def off(self) -> None: print("Projector: OFF")
def wide_screen(self) -> None: print("Projector: Wide screen mode")
class Lights:
def dim(self, level: int) -> None: print(f"Lights: Dimmed to {level}%")
def on(self) -> None: print("Lights: ON (full)")
class Screen:
def down(self) -> None: print("Screen: Down")
def up(self) -> None: print("Screen: Up")
# ── Facade ────────────────────────────────────────────────────────────
class HomeTheaterFacade:
"""One simple interface to the entire home theater subsystem."""
def __init__(self):
self._amp = Amplifier()
self._dvd = DVDPlayer()
self._projector = Projector()
self._lights = Lights()
self._screen = Screen()
def watch_movie(self, movie: str) -> None:
"""One method = 8 coordinated subsystem calls."""
print(f"\n🎬 Getting ready to watch '{movie}'...")
self._lights.dim(10)
self._screen.down()
self._projector.on()
self._projector.wide_screen()
self._amp.on()
self._amp.set_surround()
self._amp.set_volume(7)
self._dvd.on()
self._dvd.play(movie)
print("✅ Enjoy the movie!")
def end_movie(self) -> None:
print("\n⏹ Shutting down home theater...")
self._dvd.stop()
self._dvd.off()
self._amp.off()
self._projector.off()
self._screen.up()
self._lights.on()
print("✅ Theater off.")
# ── Client ─────────────────────────────────────────────────────────
theater = HomeTheaterFacade()
theater.watch_movie("Inception") # One call — coordinates 5 subsystems
theater.end_movie()// ─── C++ ─────────────────────────────────────────────────────────────
#include <iostream>
#include <string>
// ── Subsystem Classes ─────────────────────────────────────────────────
class Amplifier {
public:
void on() { std::cout << "Amplifier: ON\n"; }
void off() { std::cout << "Amplifier: OFF\n"; }
void setVolume(int v) { std::cout << "Amplifier: Volume → " << v << "\n"; }
void setSurround() { std::cout << "Amplifier: Surround ON\n"; }
};
class DVDPlayer {
public:
void on() { std::cout << "DVD Player: ON\n"; }
void off() { std::cout << "DVD Player: OFF\n"; }
void play(const std::string& m) { std::cout << "DVD Player: Playing '" << m << "'\n"; }
void stop() { std::cout << "DVD Player: Stopped\n"; }
};
class Projector {
public:
void on() { std::cout << "Projector: ON\n"; }
void off() { std::cout << "Projector: OFF\n"; }
void wideScreen() { std::cout << "Projector: Wide screen\n"; }
};
class Lights {
public:
void dim(int pct) { std::cout << "Lights: " << pct << "%\n"; }
void on() { std::cout << "Lights: Full ON\n"; }
};
class Screen {
public:
void down() { std::cout << "Screen: Down\n"; }
void up() { std::cout << "Screen: Up\n"; }
};
// ── Facade ────────────────────────────────────────────────────────────
class HomeTheaterFacade {
Amplifier amp_; DVDPlayer dvd_; Projector proj_; Lights lights_; Screen screen_;
public:
void watchMovie(const std::string& movie) {
std::cout << "\nGetting ready to watch '" << movie << "'...\n";
lights_.dim(10); screen_.down(); proj_.on(); proj_.wideScreen();
amp_.on(); amp_.setSurround(); amp_.setVolume(7);
dvd_.on(); dvd_.play(movie);
}
void endMovie() {
std::cout << "\nShutting down...\n";
dvd_.stop(); dvd_.off(); amp_.off(); proj_.off(); screen_.up(); lights_.on();
}
};
int main() {
HomeTheaterFacade theater;
theater.watchMovie("Inception");
theater.endMovie();
}// ─── Java ─────────────────────────────────────────────────────────────
// ── Subsystem Classes ─────────────────────────────────────────────────
class Amplifier {
void on() { System.out.println("Amplifier: ON"); }
void off() { System.out.println("Amplifier: OFF"); }
void setVolume(int v){ System.out.println("Amplifier: Volume → " + v); }
void setSurround() { System.out.println("Amplifier: Surround ON"); }
}
class DVDPlayer {
void on() { System.out.println("DVD Player: ON"); }
void off() { System.out.println("DVD Player: OFF"); }
void play(String m) { System.out.println("DVD Player: Playing '" + m + "'"); }
void stop() { System.out.println("DVD Player: Stopped"); }
}
class Projector {
void on() { System.out.println("Projector: ON"); }
void off() { System.out.println("Projector: OFF"); }
void wideScreen() { System.out.println("Projector: Wide screen"); }
}
class Lights {
void dim(int pct) { System.out.println("Lights: " + pct + "%"); }
void on() { System.out.println("Lights: Full ON"); }
}
class Screen {
void down() { System.out.println("Screen: Down"); }
void up() { System.out.println("Screen: Up"); }
}
// ── Facade ────────────────────────────────────────────────────────────
class HomeTheaterFacade {
private final Amplifier amp = new Amplifier();
private final DVDPlayer dvd = new DVDPlayer();
private final Projector proj = new Projector();
private final Lights lights = new Lights();
private final Screen screen = new Screen();
void watchMovie(String movie) {
System.out.println("\n🎬 Getting ready for '" + movie + "'...");
lights.dim(10); screen.down(); proj.on(); proj.wideScreen();
amp.on(); amp.setSurround(); amp.setVolume(7);
dvd.on(); dvd.play(movie);
}
void endMovie() {
System.out.println("\n⏹ Shutting down...");
dvd.stop(); dvd.off(); amp.off(); proj.off(); screen.up(); lights.on();
}
}
class FacadeDemo {
public static void main(String[] args) {
HomeTheaterFacade theater = new HomeTheaterFacade();
theater.watchMovie("Inception");
theater.endMovie();
}
}// ─── JavaScript ───────────────────────────────────────────────────────
// ── Subsystem Classes ─────────────────────────────────────────────────
class Amplifier {
on() { console.log("Amplifier: ON"); }
off() { console.log("Amplifier: OFF"); }
setVolume(v) { console.log(`Amplifier: Volume → ${v}`); }
setSurround() { console.log("Amplifier: Surround ON"); }
}
class DVDPlayer {
on() { console.log("DVD Player: ON"); }
off() { console.log("DVD Player: OFF"); }
play(movie) { console.log(`DVD Player: Playing '${movie}'`); }
stop() { console.log("DVD Player: Stopped"); }
}
class Projector {
on() { console.log("Projector: ON"); }
off() { console.log("Projector: OFF"); }
wideScreen() { console.log("Projector: Wide screen"); }
}
class Lights {
dim(pct) { console.log(`Lights: ${pct}%`); }
on() { console.log("Lights: Full ON"); }
}
class Screen {
down() { console.log("Screen: Down"); }
up() { console.log("Screen: Up"); }
}
// ── Facade ────────────────────────────────────────────────────────────
class HomeTheaterFacade {
#amp = new Amplifier(); #dvd = new DVDPlayer();
#proj = new Projector(); #lights = new Lights(); #screen = new Screen();
watchMovie(movie) {
console.log(`\n🎬 Getting ready for '${movie}'...`);
this.#lights.dim(10); this.#screen.down(); this.#proj.on(); this.#proj.wideScreen();
this.#amp.on(); this.#amp.setSurround(); this.#amp.setVolume(7);
this.#dvd.on(); this.#dvd.play(movie);
}
endMovie() {
console.log("\n⏹ Shutting down...");
this.#dvd.stop(); this.#dvd.off(); this.#amp.off();
this.#proj.off(); this.#screen.up(); this.#lights.on();
}
}
const theater = new HomeTheaterFacade();
theater.watchMovie("Inception");
theater.endMovie();// ─── C# ──────────────────────────────────────────────────────────────
using System;
class Amplifier {
public void On() => Console.WriteLine("Amplifier: ON");
public void Off() => Console.WriteLine("Amplifier: OFF");
public void SetVolume(int v)=> Console.WriteLine($"Amplifier: Volume → {v}");
public void SetSurround() => Console.WriteLine("Amplifier: Surround ON");
}
class DVDPlayer {
public void On() => Console.WriteLine("DVD Player: ON");
public void Off() => Console.WriteLine("DVD Player: OFF");
public void Play(string m) => Console.WriteLine($"DVD Player: Playing '{m}'");
public void Stop() => Console.WriteLine("DVD Player: Stopped");
}
class Projector {
public void On() => Console.WriteLine("Projector: ON");
public void Off() => Console.WriteLine("Projector: OFF");
public void WideScreen() => Console.WriteLine("Projector: Wide screen");
}
class Lights {
public void Dim(int pct) => Console.WriteLine($"Lights: {pct}%");
public void On() => Console.WriteLine("Lights: Full ON");
}
class Screen {
public void Down() => Console.WriteLine("Screen: Down");
public void Up() => Console.WriteLine("Screen: Up");
}
class HomeTheaterFacade {
readonly Amplifier amp = new(); readonly DVDPlayer dvd = new();
readonly Projector proj = new(); readonly Lights lights = new();
readonly Screen scr = new();
public void WatchMovie(string movie) {
Console.WriteLine($"\n🎬 Getting ready for '{movie}'...");
lights.Dim(10); scr.Down(); proj.On(); proj.WideScreen();
amp.On(); amp.SetSurround(); amp.SetVolume(7);
dvd.On(); dvd.Play(movie);
}
public void EndMovie() {
Console.WriteLine("\n⏹ Shutting down...");
dvd.Stop(); dvd.Off(); amp.Off(); proj.Off(); scr.Up(); lights.On();
}
static void Main() {
var theater = new HomeTheaterFacade();
theater.WatchMovie("Inception");
theater.EndMovie();
}
}
Key Takeaways
- Provides a single, simplified interface to a complex subsystem.
- Clients only know the facade — not the 5+ subsystem classes behind it.
- Subsystem classes remain fully functional and accessible directly if needed.
- Promotes loose coupling — changing subsystem internals doesn’t affect the client.
- Common in API gateways, SDK wrappers, service layers in layered architecture.
- Related: Adapter Pattern, Proxy Pattern, Decorator Pattern