Facade Pattern - Simplifying Complex Subsystems
Master the Facade pattern for providing simple interfaces to complex subsystems. TypeScript examples for API gateways, library wrappers, and service layers.
Detailed Explanation
Facade Pattern
The Facade pattern provides a simplified, unified interface to a set of interfaces in a complex subsystem. It does not add new functionality; it makes existing functionality easier to use.
Why Facades Matter
Modern applications consist of many interacting components. Without a facade, client code must understand and coordinate multiple subsystem objects:
// Without Facade: client must know all subsystems
const compiler = new Lexer();
const tokens = compiler.tokenize(source);
const parser = new Parser();
const ast = parser.parse(tokens);
const typeChecker = new TypeChecker();
typeChecker.check(ast);
const codegen = new CodeGenerator();
const output = codegen.generate(ast);
With Facade
class CompilerFacade {
compile(source: string): string {
const tokens = new Lexer().tokenize(source);
const ast = new Parser().parse(tokens);
new TypeChecker().check(ast);
return new CodeGenerator().generate(ast);
}
}
// Client: one call
const output = new CompilerFacade().compile(source);
Facade vs Adapter
Facade simplifies: reduces a complex interface to a few methods. Adapter translates: makes one interface look like another. A facade creates a new, simpler interface; an adapter wraps an existing interface to match a target.
Facade vs Mediator
Both coordinate multiple objects. A Facade provides a one-way simplified interface (clients call the facade). A Mediator facilitates two-way communication between components that know about the mediator. Facades are simpler; mediators handle more complex interactions.
Layered Facades
In large systems, facades can be layered: a high-level facade delegates to lower-level facades, each abstracting its own subsystem. This creates a clean architecture with well-defined entry points at each level.
Use Case
Facade is used for API gateway services that aggregate multiple microservice calls, library wrapper classes that simplify complex library APIs, service layer classes in MVC architectures, database abstraction layers, and build system interfaces that orchestrate compilation, testing, and deployment.