Facade Pattern in JavaScript

Photo by Growtika on Unsplash

Facade Pattern in JavaScript

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();