← Back to All Design Patterns

Facade Pattern

🎯 Explain Like I'm 5...

Imagine you want to watch a movie at home. You have a TV, a sound system, a DVD player, and special lights - so many things! 📺

😟 The Problem:

  • Turn on the TV using its remote
  • Turn on the sound system using its remote
  • Turn on the DVD player using its remote
  • Dim the lights using the light switch
  • So many remotes! So many buttons! So confusing! 😵

💡 The Solution - One Simple Remote!

  • Get a UNIVERSAL REMOTE! 🎮
  • It has just ONE button: 'Watch Movie'
  • Press it, and it does ALL the hard work for you!
  • It turns on the TV, sound system, DVD player, and dims the lights!
  • You don't need to know how it works - just press ONE button! 🎉

🌟 The Key Idea:

A Facade is like a SIMPLE remote control that hides all the complicated stuff! You press ONE button instead of dealing with many complicated remotes and switches! 🎛️

🚀 Why Is This Pattern Useful?

  • Make complex systems easy to use with a simple interface!
  • Hide all the complicated details behind one simple control!
  • Users don't need to learn how everything works inside!

📋 Pattern Purpose

The Facade pattern provides a simplified, unified interface to a complex subsystem. It makes the subsystem easier to use by hiding its complexity behind a simple interface.

⚡ When to Use Facade Pattern

  • You want to provide a simple interface to a complex subsystem
  • You need to decouple the client from many subsystem components
  • You want to layer your subsystems with entry points at each level
  • You have many interdependent classes with complex interactions

💻 Java Implementations

Example 1: Home Theater System Facade

Simplifying a complex home entertainment system with multiple devices.

Television.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Subsystem Component 1
public class Television {
public void on() {
System.out.println("TV: Turning on...");
}
public void off() {
System.out.println("TV: Turning off...");
}
public void setInput(String input) {
System.out.println("TV: Setting input to " + input);
}
}
SoundSystem.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Subsystem Component 2
public class SoundSystem {
public void on() {
System.out.println("Sound System: Powering on...");
}
public void off() {
System.out.println("Sound System: Powering off...");
}
public void setVolume(int level) {
System.out.println("Sound System: Setting volume to " + level);
}
public void setSurroundSound() {
System.out.println("Sound System: Enabling 5.1 surround sound");
}
}
DVDPlayer.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Subsystem Component 3
public class DVDPlayer {
public void on() {
System.out.println("DVD Player: Turning on...");
}
public void off() {
System.out.println("DVD Player: Turning off...");
}
public void play(String movie) {
System.out.println("DVD Player: Playing '" + movie + "'");
}
public void stop() {
System.out.println("DVD Player: Stopped");
}
}
Lights.java
java
1
2
3
4
5
6
7
8
9
10
// Subsystem Component 4
public class Lights {
public void dim(int level) {
System.out.println("Lights: Dimming to " + level + "%");
}
public void on() {
System.out.println("Lights: Turning on to full brightness");
}
}
HomeTheaterFacade.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Facade - Simple interface to complex subsystems
public class HomeTheaterFacade {
private Television tv;
private SoundSystem soundSystem;
private DVDPlayer dvdPlayer;
private Lights lights;
public HomeTheaterFacade(Television tv, SoundSystem soundSystem,
DVDPlayer dvdPlayer, Lights lights) {
this.tv = tv;
this.soundSystem = soundSystem;
this.dvdPlayer = dvdPlayer;
this.lights = lights;
}
// Simple method that hides complex operations
public void watchMovie(String movie) {
System.out.println("\n=== Getting ready to watch movie... ===");
lights.dim(10);
tv.on();
tv.setInput("DVD");
soundSystem.on();
soundSystem.setVolume(5);
soundSystem.setSurroundSound();
dvdPlayer.on();
dvdPlayer.play(movie);
System.out.println("=== Enjoy your movie! ===\n");
}
public void endMovie() {
System.out.println("\n=== Shutting down home theater... ===");
dvdPlayer.stop();
dvdPlayer.off();
soundSystem.off();
tv.off();
lights.on();
System.out.println("=== Movie time is over! ===\n");
}
}
HomeTheaterDemo.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Client code - much simpler!
public class HomeTheaterDemo {
public static void main(String[] args) {
// Create all the complex subsystem components
Television tv = new Television();
SoundSystem soundSystem = new SoundSystem();
DVDPlayer dvdPlayer = new DVDPlayer();
Lights lights = new Lights();
// Create the facade
HomeTheaterFacade homeTheater =
new HomeTheaterFacade(tv, soundSystem, dvdPlayer, lights);
// Watch a movie with just ONE method call!
homeTheater.watchMovie("The Matrix");
// ... enjoy the movie ...
// End the movie with just ONE method call!
homeTheater.endMovie();
// WITHOUT FACADE, you would need to call:
// lights.dim(10);
// tv.on();
// tv.setInput("DVD");
// soundSystem.on();
// soundSystem.setVolume(5);
// soundSystem.setSurroundSound();
// dvdPlayer.on();
// dvdPlayer.play("The Matrix");
// ... and then reverse all of this to end the movie!
}
}

Example 2: Computer Startup Facade

Hiding the complex computer boot process behind a simple start method.

CPU.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Subsystem Component 1
public class CPU {
public void freeze() {
System.out.println("CPU: Freezing processor");
}
public void jump(long position) {
System.out.println("CPU: Jumping to position " + position);
}
public void execute() {
System.out.println("CPU: Executing instructions");
}
}
Memory.java
java
1
2
3
4
5
6
7
8
9
10
11
// Subsystem Component 2
public class Memory {
public void load(long position, byte[] data) {
System.out.println("Memory: Loading " + data.length +
" bytes at position " + position);
}
public void initialize() {
System.out.println("Memory: Initializing RAM");
}
}
HardDrive.java
java
1
2
3
4
5
6
7
8
9
10
11
12
// Subsystem Component 3
public class HardDrive {
public byte[] read(long lba, int size) {
System.out.println("Hard Drive: Reading " + size +
" bytes from sector " + lba);
return new byte[size];
}
public void spinUp() {
System.out.println("Hard Drive: Spinning up disk");
}
}
ComputerFacade.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Facade - Simplifies complex computer boot process
public class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
// Boot sector position and size
private static final long BOOT_ADDRESS = 0x00;
private static final long BOOT_SECTOR = 0x00;
private static final int SECTOR_SIZE = 512;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
// Simple start method hides complex boot process
public void start() {
System.out.println("\n=== Starting Computer... ===");
// Complex boot sequence
cpu.freeze();
memory.initialize();
hardDrive.spinUp();
// Load boot sector
byte[] bootSector = hardDrive.read(BOOT_SECTOR, SECTOR_SIZE);
memory.load(BOOT_ADDRESS, bootSector);
// Start execution
cpu.jump(BOOT_ADDRESS);
cpu.execute();
System.out.println("=== Computer Started! ===\n");
}
public void shutdown() {
System.out.println("\n=== Shutting Down Computer... ===");
System.out.println("Computer: Closing all applications");
System.out.println("Computer: Saving state");
System.out.println("Computer: Powering off");
System.out.println("=== Computer Shut Down ===\n");
}
}
ComputerDemo.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Client code
public class ComputerDemo {
public static void main(String[] args) {
// Create the computer facade
ComputerFacade computer = new ComputerFacade();
// Start the computer with ONE simple call!
computer.start();
System.out.println("... User works on computer ...");
// Shut down with ONE simple call!
computer.shutdown();
// WITHOUT FACADE, you would need to:
// cpu.freeze();
// memory.initialize();
// hardDrive.spinUp();
// byte[] bootSector = hardDrive.read(0x00, 512);
// memory.load(0x00, bootSector);
// cpu.jump(0x00);
// cpu.execute();
// ... very complex and error-prone!
}
}

🌍 Real-World Examples

  • 📺TV Universal Remote: One remote controls TV, sound, DVD, and lights
  • 🚗Car Ignition: Turn key to start complex engine, fuel, electrical systems
  • 🍽️Restaurant: Order food without knowing kitchen's complex operations
  • 🗄️JDBC: Simplified database interface hides complex SQL operations
  • 🌐Web Frameworks: Simple API hides complex HTTP, routing, rendering

✅ Benefits

  • Simplicity: Provides easy-to-use interface to complex system
  • Loose Coupling: Reduces dependencies between clients and subsystems
  • Layering: Helps structure system into layers
  • Flexibility: Can change subsystems without affecting clients

⚠️ Drawbacks

  • ⚠️God Object: Facade can become too large and coupled to all subsystems
  • ⚠️Limited Functionality: May not expose all features of subsystems
  • ⚠️Additional Layer: Adds one more layer of abstraction

🔑 Key Points to Remember

  • 1️⃣Facade provides a simple interface to complex subsystems
  • 2️⃣Clients use facade instead of accessing subsystems directly
  • 3️⃣Subsystems are still accessible if advanced features are needed
  • 4️⃣Different from Adapter - Facade simplifies many classes, Adapter wraps one
  • 5️⃣Different from Decorator - Facade simplifies interface, Decorator adds behavior

💪 Practice Scenarios

  • Create a Banking Facade that simplifies account, transaction, and loan operations
  • Build a Email System Facade that handles SMTP, IMAP, and authentication
  • Implement a Shopping Cart Facade that manages inventory, pricing, and checkout
  • Design a Travel Booking Facade for flights, hotels, and car rentals
  • Create a Game Facade that simplifies graphics, sound, and input systems