Posts

Facade

June 23, 2025
Facade Pattern
The Facade Pattern provides a unified and simplified interface to a complex subsystem. It hides the complexity of the underlying system and exposes only the features clients need.
When integrating with complex libraries or frameworks, clients must understand:
  • Many interdependent classes
  • Initialization order
  • Data transformations This couples business logic tightly to low-level details, making it hard to maintain.

The Facade:
  • Offers a simplified interface
  • Manages interactions with the subsystem
  • Keeps client code clean and decoupled
This makes it easier to use, test, and replace the subsystem.
Phone customer service: When you place an order, you talk to one operator (facade). You don’t need to deal with billing, shipping, and inventory systems separately.
  • Client: Calls the Facade
  • Facade: Provides simple methods
  • Subsystem Classes: Do the real work (but hidden from the client)

Javascript
// Subsystem classes (complex and low-level)
class VideoFile {
  constructor(name) {
    this.name = name;
  }
}

class CodecFactory {
  extract(file) {
    return file.name.endsWith(".mp4") ? new MPEG4Codec() : new OggCodec();
  }
}

class MPEG4Codec {}
class OggCodec {}

class BitrateReader {
  static read(filename, codec) {
    console.log(`Reading file ${filename} with ${codec.constructor.name}`);
    return "bufferedData";
  }

  static convert(buffer, codec) {
    console.log(`Converting with ${codec.constructor.name}`);
    return `converted-${buffer}`;
  }
}

class AudioMixer {
  fix(data) {
    console.log("Fixing audio...");
    return `fixed-${data}`;
  }
}

// Facade: hides subsystem complexity
class VideoConverter {
  convert(filename, format) {
    const file = new VideoFile(filename);
    const sourceCodec = new CodecFactory().extract(file);
    const destinationCodec =
      format === "mp4" ? new MPEG4Codec() : new OggCodec();
    let buffer = BitrateReader.read(filename, sourceCodec);
    let result = BitrateReader.convert(buffer, destinationCodec);
    result = new AudioMixer().fix(result);
    return result;
  }
}

// Client: uses the Facade
const converter = new VideoConverter();
const mp4 = converter.convert("funny-cats.ogg", "mp4");
console.log("Output:", mp4);
Reading file funny-cats.ogg with OggCodec
Converting with MPEG4Codec
Fixing audio...
Output: fixed-converted-bufferedData

  • You want to simplify a complex or evolving subsystem
  • You need to shield client code from low-level API changes
  • You want to isolate third-party library usage

✅ Pros:
  • Reduces client–subsystem coupling
  • Easier to update or replace subsystem
  • Simplifies usage
❌ Cons:
  • Can turn into a God Object if overloaded
  • Might limit access to full functionality
On this page