🧩 Facade パターン
✅ 設計意図
- 複雑な処理を 1 つの**分かりやすい窓口(Facade)**にまとめる
- 利用者は目的ベースの簡潔な APIを使えるようにする
✅ 適用理由
- 呼び出し元の責務を減らし、再利用しやすい統一的なインターフェースに整理
- 背後の実装が変わっても呼び出し側に影響を与えにくい
✅ 向いているシーン
- 複数のサービス・処理を組み合わせた「よく使う処理パターン」がある場合
- フレームワークやモジュールの統合窓口
✅ コード例
- TypeScript
- PHP
- Python
class AuthService {
authenticate(userId: string): boolean {
console.log(`ユーザー認証: ${userId}`);
return true;
}
}
class UserProfileService {
load(userId: string): object {
console.log(`プロフィール取得: ${userId}`);
return { name: "Hiroshi", id: userId };
}
}
class AuditService {
log(action: string) {
console.log(`[監査ログ] ${action}`);
}
}
// Facade
class UserProfileFacade {
private auth = new AuthService();
private profile = new UserProfileService();
private audit = new AuditService();
show(userId: string) {
if (this.auth.authenticate(userId)) {
const profile = this.profile.load(userId);
console.log(profile);
this.audit.log("プロフィール表示");
}
}
}
// 利用例
const facade = new UserProfileFacade();
facade.show("user-123");
<?php
class AuthService {
public function authenticate(string $userId): bool {
echo "ユーザー認証: {$userId}\n";
return true;
}
}
class UserProfileService {
public function load(string $userId): array {
echo "プロフィール取得: {$userId}\n";
return ["name" => "Hiroshi", "id" => $userId];
}
}
class AuditService {
public function log(string $action): void {
echo "[監査ログ] {$action}\n";
}
}
// Facade
class UserProfileFacade {
private AuthService $auth;
private UserProfileService $profile;
private AuditService $audit;
public function __construct() {
$this->auth = new AuthService();
$this->profile = new UserProfileService();
$this->audit = new AuditService();
}
public function show(string $userId): void {
if ($this->auth->authenticate($userId)) {
$profile = $this->profile->load($userId);
print_r($profile);
$this->audit->log("プロフィール表示");
}
}
}
// 利用例
$facade = new UserProfileFacade();
$facade->show("user-123");
class AuthService:
def authenticate(self, user_id: str) -> bool:
print(f"ユーザー認証: {user_id}")
return True
class UserProfileService:
def load(self, user_id: str) -> dict:
print(f"プロフィール取得: {user_id}")
return {"name": "Hiroshi", "id": user_id}
class AuditService:
def log(self, action: str):
print(f"[監査ログ] {action}")
# Facade
class UserProfileFacade:
def __init__(self):
self.auth = AuthService()
self.profile = UserProfileService()
self.audit = AuditService()
def show(self, user_id: str):
if self.auth.authenticate(user_id):
profile = self.profile.load(user_id)
print(profile)
self.audit.log("プロフィール表示")
# 利用例
facade = UserProfileFacade()
facade.show("user-123")
✅ 解説
このコードは Facade
パターン を使用して、複数のサブシステム(AuthService
, UserProfileService
, AuditService
)を
統一的に利用できるようにする設計を実現している。
Facade
パターンは、複雑なサブシステムを簡単に利用できるようにするための統一インターフェースを提供するデザインパターン。
1. Facade パターンの概要
- Subsystem Classes: 複雑な処理を提供するクラス
- このコードでは
AuthService
,UserProfileService
,AuditService
が該当
- このコードでは
- Facade: サブシステムを統一的に利用するための簡潔なインターフェースを提供するクラス
- このコードでは
UserProfileFacade
が該当
- このコードでは
- Client:
Facade
を利用してサブシステムを操作するクラス- このコードでは
facade.show("user-123")
を呼び出す部分が該当
- このコードでは
2. 主なクラスとその役割
AuthService
- サブシステムの一部
- ユーザー認証を行うクラス
UserProfileService
- サブシステムの一部
- ユーザープロフィールを取得するクラス
AuditService
- サブシステムの一部
- 操作の監査ログを記録するクラス
UserProfileFacade
Facade
クラス- サブシステムを統合し、
show
メソッドでユーザー認証、プロフィール取得、監査ログ記録を一括して実行
- クライアントコード
UserProfileFacade
を利用して、ユーザーのプロフィールを表示
3. UML クラス図
4. Facade パターンの利点
- 簡潔なインターフェース: クライアントは複雑なサブシステムを意識せずに操作可能
- 疎結合: クライアントとサブシステム間の結合度を低減
- 保守性向上: サブシステムの変更が
Facade
内に閉じ込められるため、クライアントコードへの影響を最小化
この設計は、複雑な内部処理を隠蔽し、クライアントに対して簡潔なインターフェースを提供する必要がある場面で非常に有効であり、 コードの可読性と保守性を向上させる。