🧩 Facade Pattern
✅ Intent
- Simplify access to complex subsystems or multiple operations by providing a single, unified interface
- Hide implementation details and workflow from the client, enabling simplified and safe usage
- Introduce a facade as a clean entry point to reduce coupling between caller and implementation
✅ Motivation
- You want to wrap multiple lower-level modules or legacy APIs into a single access point
- Client code contains scattered logic for initialization, formatting, or side effects
- You want to refactor toward a maintainable and change-resilient structure
- Provide a clean API to UIs or service layers without exposing internal complexity
✅ When to Use
- You want to wrap complex low-level operations (e.g., API calls, config, logging, notifications) into a single method
- You are dealing with multiple external services or legacy APIs and want to present a unified interface
- You need to abstract an entire process to support testing or mocking
- You want the caller's code to be as simple and safe as possible
- You require controlled, fail-safe orchestration of multi-step processes (e.g., service integration)
✅ Code Example
- TypeScript
- PHP
- Python
// レガシーAPIや内部処理(複雑)
class LegacyPrinter {
printText(text: string) {
console.log(`*** ${text} ***`);
}
}
class FooterGenerator {
getFooter(): string {
return "---- END ----";
}
}
// Facade(簡潔なインターフェース)
class PrintFacade {
private printer = new LegacyPrinter();
private footerGen = new FooterGenerator();
printWithFooter(text: string) {
const formatted = text.toUpperCase();
this.printer.printText(formatted);
const footer = this.footerGen.getFooter();
this.printer.printText(footer);
}
}
// 呼び出し元
class ReportGenerator {
constructor(private facade: PrintFacade) {}
printSummary(text: string) {
this.facade.printWithFooter(text);
}
}
// 利用例
const printer = new PrintFacade();
const report = new ReportGenerator(printer);
report.printSummary("月次レポート");
<?php
class LegacyPrinter {
public function printText(string $text): void {
echo "*** {$text} ***\n";
}
}
class FooterGenerator {
public function getFooter(): string {
return "---- END ----";
}
}
class PrintFacade {
private LegacyPrinter $printer;
private FooterGenerator $footerGen;
public function __construct() {
$this->printer = new LegacyPrinter();
$this->footerGen = new FooterGenerator();
}
public function printWithFooter(string $text): void {
$formatted = strtoupper($text);
$this->printer->printText($formatted);
$footer = $this->footerGen->getFooter();
$this->printer->printText($footer);
}
}
class ReportGenerator {
public function __construct(private PrintFacade $facade) {}
public function printSummary(string $text): void {
$this->facade->printWithFooter($text);
}
}
// 利用例
$facade = new PrintFacade();
$report = new ReportGenerator($facade);
$report->printSummary("月次レポート");
class LegacyPrinter:
def print_text(self, text: str):
print(f"*** {text} ***")
class FooterGenerator:
def get_footer(self) -> str:
return "---- END ----"
class PrintFacade:
def __init__(self):
self.printer = LegacyPrinter()
self.footer_gen = FooterGenerator()
def print_with_footer(self, text: str):
formatted = text.upper()
self.printer.print_text(formatted)
footer = self.footer_gen.get_footer()
self.printer.print_text(footer)
class ReportGenerator:
def __init__(self, facade: PrintFacade):
self.facade = facade
def print_summary(self, text: str):
self.facade.print_with_footer(text)
# 利用例
facade = PrintFacade()
report = ReportGenerator(facade)
report.print_summary("月次レポート")
✅ Explanation
This code uses the Facade
pattern to hide complex internal logic—such as the legacy printer and footer generation—and expose a simplified interface through PrintFacade
.
The Facade
pattern provides a unified interface to a set of subsystems, enabling clients to interact with them more easily and safely.
1. Overview of the Facade Pattern
-
Subsystem Classes: Provide complex or low-level functionality
- Represented by
LegacyPrinter
andFooterGenerator
- Represented by
-
Facade: Provides a simplified interface for using multiple subsystems together
- Represented by
PrintFacade
- Represented by
-
Client: Uses the facade without needing to understand the underlying subsystems
- Represented by
ReportGenerator
- Represented by
2. Key Classes and Their Roles
-
LegacyPrinter
- Part of the subsystem
- Provides low-level text printing functionality
-
FooterGenerator
- Part of the subsystem
- Generates footer text to append to documents
-
PrintFacade
- The facade class
- Orchestrates the subsystems and provides a simple method:
printWithFooter
-
ReportGenerator
- The client class
- Uses the
PrintFacade
to print a report with a footer without knowing internal details
3. UML Class Diagram
4. Benefits of the Facade Pattern
- Simplified interface: Clients can interact with complex systems through a minimal set of methods
- Reduced coupling: Client code is decoupled from the underlying implementation
- Improved maintainability: Changes to the subsystems are isolated inside the
Facade
, reducing impact on client code
This design is especially useful when dealing with complex or fragile internal processes that must be abstracted away from external code.
It improves clarity, safety, and testability across the application.