🧩 Facade Pattern
✅ Intent
- Combine multiple underlying systems—such as logging and configuration—into a single, simplified interface
- Allow clients to use a clean API without needing to know about internal complexities
✅ Motivation
- Abstract and hide the details of how logs are written and configuration values are retrieved
- Ensure that client code is not affected even if external libraries or implementations change
✅ When to Use
- When a subsystem becomes complex and the goal is to offer a simple and unified access point
✅ Code Example
- TypeScript
- PHP
- Python
class Config {
static isDebug(): boolean {
return process.env.DEBUG_MODE === "true";
}
}
class LoggerFacade {
static log(message: string) {
console.log(`[LOG] ${message}`);
}
static debug(message: string) {
if (Config.isDebug()) {
console.log(`[DEBUG] ${message}`);
}
}
}
// 利用例
class OrderService {
createOrder(orderId: string) {
LoggerFacade.log(`注文作成: ${orderId}`);
LoggerFacade.debug(`注文詳細: ${orderId}`);
}
}
<?php
class Config {
public static function isDebug(): bool {
return getenv("DEBUG_MODE") === "true";
}
}
class LoggerFacade {
public static function log(string $message): void {
echo "[LOG] {$message}\n";
}
public static function debug(string $message): void {
if (Config::isDebug()) {
echo "[DEBUG] {$message}\n";
}
}
}
class OrderService {
public function createOrder(string $orderId): void {
LoggerFacade::log("注文作成: {$orderId}");
LoggerFacade::debug("注文詳細: {$orderId}");
}
}
import os
class Config:
@staticmethod
def is_debug() -> bool:
return os.environ.get("DEBUG_MODE") == "true"
class LoggerFacade:
@staticmethod
def log(message: str):
print(f"[LOG] {message}")
@staticmethod
def debug(message: str):
if Config.is_debug():
print(f"[DEBUG] {message}")
class OrderService:
def create_order(self, order_id: str):
LoggerFacade.log(f"注文作成: {order_id}")
LoggerFacade.debug(f"注文詳細: {order_id}")
✅ Explanation
This code uses the Facade
pattern to introduce a LoggerFacade
that simplifies how log output and debug checks are handled.
The Facade
pattern provides a unified interface to a set of interfaces in a subsystem, making it easier for clients to use the subsystem.
1. Overview of the Facade Pattern
-
Subsystem Classes: Classes that provide the actual logic behind the scenes
- In this case:
Config
- In this case:
-
Facade: Provides a simplified, high-level API for the subsystem
- In this case:
LoggerFacade
- In this case:
-
Client: Uses the
Facade
rather than interacting with each subsystem class directly- In this case:
OrderService
- In this case:
2. Key Classes and Their Roles
-
Config
- A subsystem component
- Reads environment variables (like
DEBUG_MODE
) to determine debug behavior
-
LoggerFacade
- The
Facade
class - Provides a unified interface for logging (including debug-only logging)
- Internally uses
Config
to determine behavior
- The
-
OrderService
- Client class
- Logs messages through
LoggerFacade
, with no need to understand debug configuration
3. UML Class Diagram
4. Benefits of the Facade Pattern
- Simplified Interface: Clients don’t need to understand or manage the subsystem directly
- Loose Coupling: Client and subsystem are decoupled via the facade
- Better Maintainability: Changes in the subsystem are encapsulated within the facade, reducing client-side impact
This design is ideal when simplifying complex internal logic is necessary, or when offering a stable and clean interface to potentially volatile underlying code.
It improves both readability and maintainability.