Skip to main content

Facade Pattern

Provide simplified interface to complex subsystems

Pattern Overview

🔗 The Facade Pattern - Simplified Interface

Provides a simplified interface to a complex subsystem by hiding complexity behind a single, easy-to-use interface. Perfect for clean APIs!

  • Core Problem Solved:
  • Hide complexity of subsystems from clients
  • Provide unified interface to multiple related classes
  • Reduce coupling between client and subsystem
  • Simplify common use cases and workflows
🔍 Three Implementation Approaches:
  • Single Facade: One class wrapping multiple subsystems
  • Multiple Facades: Different facades for different use cases
  • Layered Facade: Hierarchical simplification of complex systems
  • Real-World Applications:
  • API wrappers that simplify complex REST/GraphQL calls
  • Library wrappers that provide easier interfaces
  • System integration layers for multiple services
  • E-commerce order processing workflows
  • Media processing pipelines
  • Database abstraction layers
  • Modern Usage Examples:
  • jQuery as facade over DOM manipulation
  • Express.js as facade over Node.js HTTP
  • ORMs as facades over SQL databases
  • Cloud SDK facades over service APIs

Examples:
Application initialization
Input:
facade.initialize(config)
Output:
All services (DB, cache, logging, validation) initialized
E-commerce order placement
Input:
ecommerceFacade.placeOrder(orderData)
Output:
{ success: true, orderId: 'order_1234567890' }
Media file processing
Input:
mediaFacade.processMediaFiles([audioFile, videoFile, imageFile])
Output:
All files processed with respective operations applied

Concepts

Interface SimplificationSubsystem AbstractionComplexity HidingUnified APILoose Coupling

Complexity Analysis

Time:O(1)
Space:O(1)

Implementation

application-facade

Time: O(1) | Space: O(1)
// Complex subsystems
class DatabaseService {
  connect(connectionString: string): void { /* ... */ }
  executeQuery(query: string): any[] { /* ... */ }
  close(): void { /* ... */ }
}

class CacheService {
  connect(host: string, port: number): void { /* ... */ }
  get(key: string): any { /* ... */ }
  set(key: string, value: any, ttl: number): void { /* ... */ }
}

class LoggingService {
  initialize(logLevel: string, outputPath: string): void { /* ... */ }
  log(level: string, message: string): void { /* ... */ }
}

// Facade simplifies interaction with all subsystems
class ApplicationFacade {
  private db: DatabaseService;
  private cache: CacheService;
  private logger: LoggingService;

  constructor() {
    this.db = new DatabaseService();
    this.cache = new CacheService();
    this.logger = new LoggingService();
  }

  // Single method handles complex initialization
  public initialize(config: {
    dbConnection: string;
    cacheHost: string;
    cachePort: number;
    logLevel: string;
    logPath: string;
  }): void {
    this.logger.initialize(config.logLevel, config.logPath);
    this.logger.log('info', 'Starting initialization');

    this.db.connect(config.dbConnection);
    this.cache.connect(config.cacheHost, config.cachePort);

    this.logger.log('info', 'Initialization complete');
  }

  // Simplified user operations
  public getUser(id: number): any {
    this.logger.log('info', `Fetching user ${id}`);

    // Check cache first
    let user = this.cache.get(`user:${id}`);
    if (!user) {
      user = this.db.executeQuery(`SELECT * FROM users WHERE id = ${id}`)[0];
      if (user) this.cache.set(`user:${id}`, user, 300);
    }

    return user;
  }
}