1. パターンの意図
ファサード(Facade)パターン は、
複雑なサブシステムにシンプルな統一インターフェースを提供する デザインパターンです。
解決する問題
- 複雑な処理(多くのクラスや API 呼び出し)が絡んでおり、クライアントから扱いにくい
- クライアントがサブシステムの詳細を知りすぎて依存が強まる
- 「窓口」を用意してシンプルにしたい
ポイント
- Facade がサブシステムへの 統一入口 となる
- クライアントは Facade だけ を呼び出せばよい
- 内部の複雑さを隠蔽できる(Encapsulation)
2. UML 図
- Facade:サブシステムをまとめる窓口
- Subsystem:複雑な処理を持つ各コンポーネント
- Client:Facade を通して処理する
3. Flutter / Dart 実装例
複雑なサブシステム
class AuthService {
void login(String user, String pass) => print("Auth: $user logged in");
}
class PaymentService {
void pay(int amount) => print("Paid $amount yen");
}
class NotificationService {
void notify(String message) => print("Notification: $message");
}
ファサード
class ShopFacade {
final AuthService _auth = AuthService();
final PaymentService _payment = PaymentService();
final NotificationService _notify = NotificationService();
void purchase(String user, String pass, int amount) {
_auth.login(user, pass);
_payment.pay(amount);
_notify.notify("Purchase completed!");
}
}
利用例
void main() {
var shop = ShopFacade();
shop.purchase("Anna", "pass123", 1200);
}
出力:
Auth: Anna logged in
Paid 1200 yen
Notification: Purchase completed!
👉 クライアントは purchase
だけを呼べば済む。
4. Android / Kotlin 実装例
サブシステム
class AuthService {
fun login(user: String, pass: String) = println("Auth: $user logged in")
}
class PaymentService {
fun pay(amount: Int) = println("Paid $amount yen")
}
class NotificationService {
fun notify(message: String) = println("Notification: $message")
}
ファサード
class ShopFacade {
private val auth = AuthService()
private val payment = PaymentService()
private val notifyService = NotificationService()
fun purchase(user: String, pass: String, amount: Int) {
auth.login(user, pass)
payment.pay(amount)
notifyService.notify("Purchase completed!")
}
}
利用例
fun main() {
val shop = ShopFacade()
shop.purchase("Anna", "pass123", 1200)
}
5. メリット / デメリット
メリット
- クライアントが複雑な処理に直接依存しなくてよい
- 窓口を変えるだけで内部の変更に対応できる
- コードの可読性・保守性が向上
デメリット
- Facade が「神クラス化」 する危険あり
- サブシステムの柔軟性が制限される場合がある
6. 実務ユースケース
Flutter
- Repository パターンの一部として複数の DataSource をまとめる
- Platform Channel をラップして Dart からシンプルに呼べる窓口を提供
- 複数サービスをまとめて「ユースケース API」を定義
Android (Kotlin)
- Repository / UseCase 層で DB + ネットワーク + キャッシュをまとめる
- MediaPlayer API のような複雑な API をラップして簡単インターフェース化
- SDK の内部に複数モジュールがある場合の窓口提供
7. どんなときに使う?
- 複数サービスを まとめて一つのユースケースとして提供したいとき
- 内部の複雑さを隠したいとき
- サブシステムの変更にクライアントを巻き込みたくないとき
まとめ
- Facade パターンは「複雑な処理の入口を一本化する」デザインパターン
- Flutter では Repository/PlatformChannel、Android では UseCase/SDK ラッパに多用
- Decorator が“拡張”、Adapter が“不一致解消”、Facade は“簡単な窓口”