Skip to main content

🧩 Facade Pattern

✅ Intent

  • Hide complex internal processes and provide a simple interface to external callers
  • Serve as a user-friendly "single entry point" to the system

✅ Motivation

  • Allows use cases (e.g., order processing) to be invoked via a single external interface
  • Keeps responsibilities separated while providing a unified point of access

✅ When to Use

  • When business logic is modularized but should be accessed as a whole
  • When you want to encapsulate a set of related operations into a single function call

✅ Code Example

// 個別責務のクラスたち
class DiscountCalculator {
static calculate(base: number, type: string): number {
switch (type) {
case "student":
return base * 0.8;
case "member":
return base * 0.9;
default:
return base;
}
}
}

class InventoryService {
static reduce(productIds: string[]) {
console.log(`在庫を ${productIds.length} 件分減らしました`);
}
}

class EmailService {
static send(email: string, message: string) {
console.log(`メールを ${email} に送信: ${message}`);
}
}

class OrderLogger {
static log(orderId: string) {
console.log(`注文ログを記録: ${orderId}`);
}
}

// Facadeクラス
class OrderProcessor {
constructor(
private productIds: string[],
private userEmail: string,
private discountType: string
) {}

confirmOrder() {
const basePrice = this.productIds.length * 1000;
const total = DiscountCalculator.calculate(basePrice, this.discountType);

InventoryService.reduce(this.productIds);
EmailService.send(
this.userEmail,
`ご注文が確定しました(合計: ¥${total}`
);
OrderLogger.log("order-" + Math.random().toString(36).substring(2));
}
}

// 利用例
const facadeProcessor = new OrderProcessor(
["p01", "p02"],
"hiroshi@example.com",
"student"
);
facadeProcessor.confirmOrder();

✅ Explanation

This code applies the Facade pattern to hide the complex internal logic involved in order processing, exposing a simplified interface (OrderProcessor) to external callers.
The Facade pattern provides a "gateway" to a complex subsystem, allowing clients to interact with it in a streamlined manner.

1. Overview of the Facade Pattern

In this implementation, the OrderProcessor class acts as the Facade, coordinating multiple classes with distinct responsibilities:

  • DiscountCalculator: Responsible for calculating discounts
  • InventoryService: Responsible for inventory control
  • EmailService: Responsible for sending emails
  • OrderLogger: Responsible for logging order activities

2. Key Classes and Their Roles

  • DiscountCalculator

    • A utility class that calculates discounts
    • Computes the price based on the discount type (student, member, default)
  • InventoryService

    • Handles the reduction of inventory stock
  • EmailService

    • Sends messages to a specified email address
  • OrderLogger

    • Records order logs
  • OrderProcessor

    • The Facade class
    • Integrates the above subsystems and provides a simplified interface for order processing
    • The confirmOrder method performs the following steps:
      • Calculates the base price
      • Applies discounts to compute the total amount
      • Updates the inventory
      • Sends a confirmation email
      • Logs the order

3. UML Class Diagram

4. Benefits of the Facade Pattern

  • Simplified Interface: External clients can complete the entire order process by interacting only with OrderProcessor
  • Separation of Concerns: Each class has a single, well-defined responsibility, improving maintainability
  • Reusability: The underlying subsystems (DiscountCalculator, etc.) are decoupled and can be reused independently

This design effectively encapsulates complexity while maintaining clear separation of responsibilities among classes.