給一組複雜子系統一個簡化的高層入口,讓 client 透過一道「門面」就能完成常見任務,降低與內部細節的耦合。
🧠 When to Use
TIP
訊號:要做一件事得依序戳好幾個子系統類別、記住它們的呼叫順序與相依——而大多數 client 只想要那個「常見組合」。
- 想為複雜子系統提供簡單的預設入口。
- 想解耦 client 與子系統內部,降低相依面積。
- 想為分層架構定義清楚的層間進入點。
⚖️ Structure & Variants
經典版 — 一道門面包住啟動流程
// 子系統各自獨立、各有細節
class Cpu { fun boot() { /* ... */ } }
class Memory { fun load(addr: Long, data: ByteArray) { /* ... */ } }
class Disk { fun read(lba: Long): ByteArray = /* ... */ ByteArray(0) }
// Facade:把常見流程包成一個簡單呼叫
class ComputerFacade(
private val cpu: Cpu = Cpu(),
private val mem: Memory = Memory(),
private val disk: Disk = Disk(),
) {
fun start() {
mem.load(0, disk.read(0))
cpu.boot()
}
}
ComputerFacade().start() // client 不必知道啟動順序- Facade 不封死子系統:進階使用者仍可直接用 Cpu / Memory / Disk。
和 Adapter / Mediator 的差別
- Facade:把一整組子系統收斂成一個簡化入口;單向(client → 子系統)。
- Adapter:把一個不相容介面轉成目標介面,目的是相容。
- Mediator:協調多個同儕物件彼此的互動,是雙向的中介。
⚠️ Misuse & Anti-patterns
- 變成 God Object:把所有子系統功能全堆進 Facade,它就膨脹成無所不管的上帝類別。
- 強迫所有存取都走 Facade:Facade 是便利入口不是封印;該開放的進階用法仍要留口。
- 把 Facade 當 Adapter:只是要轉一個介面時,用 Facade 是殺雞用牛刀。
🔑 Takeaways
- 解決的是「子系統太複雜」:提供高層門面,封裝常見流程、降低耦合。
- Facade 提供便利而非封鎖——不阻止進階 client 直接用子系統。
- 和 Adapter(轉介面)、Mediator(協調同儕)的意圖各不相同。
No notes yet — jot your takeaways or Q&A here.