The Facade pattern is a structural design pattern that provides a simple, unified interface to a complex subsystem of classes, making it easier for clients to interact with the system. It hides the complexities of the underlying classes by providing a higher-level interface, thus promoting loose coupling between the client code and the subsystem.
Let's consider a real-world example of a multimedia system that consists of various components like a DVD player, projector, sound system, and lights. Each of these components has its API and configuration. To simplify the usage of the multimedia system, we can implement a facade that encapsulates the interaction with all the individual components and provides a single interface to the clients.
// Subsystem components
class DVDPlayer {
on() {
console.log("DVD player is on.");
}
play() {
console.log("DVD player is playing.");
}
}
class Projector {
on() {
console.log("Projector is on.");
}
setInput(inputSource) {
console.log(`Projector input set to ${inputSource}.`);
}
wideScreenMode() {
console.log("Projector is in widescreen mode.");
}
}
class SoundSystem {
on() {
console.log("Sound system is on.");
}
setVolume(volumeLevel) {
console.log(`Sound system volume set to ${volumeLevel}.`);
}
}
class Lights {
dim() {
console.log("Lights are dimmed.");
}
}
// Facade
class HomeTheaterFacade {
constructor() {
this.dvdPlayer = new DVDPlayer();
this.projector = new Projector();
this.soundSystem = new SoundSystem();
this.lights = new Lights();
}
watchMovie() {
this.lights.dim();
this.soundSystem.on();
this.soundSystem.setVolume(8);
this.projector.on();
this.projector.setInput("DVD");
this.projector.wideScreenMode();
this.dvdPlayer.on();
this.dvdPlayer.play();
}
endMovie() {
this.dvdPlayer.on();
this.projector.setInput("OFF");
this.soundSystem.setVolume(0);
this.lights.dim();
}
}
// Client
const homeTheater = new HomeTheaterFacade();
homeTheater.watchMovie();
// ...some actions...
homeTheater.endMovie();