依賴反轉原則入門:從手作甜點店學習dip

Table of contents

什麼是依賴反轉?
「業務邏輯」和「實作細節」兩端都依賴抽象
業務邏輯 ➡️ 抽象介面 ⬅️ 實作細節
用手作甜點店比喻依賴關係
舉例來說:你經營一家手作甜點店 (業務邏輯/Domain層):
需要食材來製作甜點
但你不親自去買
告訴採購部需求(Repository介面)
採購部會:
選擇供應商可能是批發市場、農場直送、進口等
買到食材(實作Repository)
這樣設計的好處
你可以專注在做甜點,你不用管食材怎麼買 →業務邏輯 依賴抽象 ⬇️
告訴採購部需求→Repository介面
採購部選擇供應商買食材→實作抽象Repository 依賴 ⬆️
原則
維基百科:https://zh.wikipedia.org/wiki/%E4%BE%9D%E8%B5%96%E5%8F%8D%E8%BD%AC%E5%8E%9F%E5%88%99
高層次的模組不應該依賴於低層次模組
高層次模組:抽象、業務規則、接近人思維
低層次模組: 實作細節、數據操作、接近電腦運作
依賴:處理怎麼做
目的:解耦高低層模組,低層細節變更時,不影響高層業務邏輯
抽象接口(介面)不應該依賴於具體實現,而具體實現應該依賴於抽象接口(介面)
- 意思是抽象接口不要有具體的實作細節
// ❌ 錯誤:介面包含市場A的具體實作細節
interface Purchase {
// 依賴特定市場的營業時間
fun buyBeforeMarketAClose()
// 依賴特定市場的付款方式
fun payWithMarketACreditCard()
// 依賴特定市場的食材
fun getMarketAIngredients(): MarketA
}
// ✅ 正確:介面只定義要做什麼,不管是從哪裡買
interface Purchase {
// 純抽象的採購行為
fun buy()
// 使用通用的食材型別
fun getIngredients(): List<Ingredient>
}
抽象:專注在做什麼而非
怎麼做,目的是隱藏實作細節。- 實現方式:介面 (Interface)、抽象類別 (Abstract Class)
目的:透過接口,允許不同的具體實作輕鬆替換。
依賴說明
依賴=直接處理怎麼做
實作程式細節
你親自去採購
依賴反轉=關注要做什麼
透過介面告知需求
只要告訴採購部需求
為什麼要依賴反轉?
有無使用依賴反轉的差異
比喻 | 甜點師 ➡️ 超市A(實作程式) | 甜點師 ➡️ 採購部(介面) ⬅️ 超市A/批發商B/農場C |
依賴狀態 | 沒有依賴反轉 | 有依賴反轉 |
特點 | 綁定特定實作、更換供應商需改動業務邏輯 | 透過介面解耦、實作可自由替換 |
程式碼示範:
// 沒有依賴反轉:
class ChefService {
// 依賴特定超市
private val marketA = MarketA()
fun getIngredients() {
marketA.buy() // 綁定實作
}
}
// ------------------------------------
// 有依賴反轉:
interface Purchase { // 採購部介面
fun buy()
}
class ChefService {
// 依賴介面
private val purchase: Purchase
fun getIngredients() {
purchase.buy() // 透過介面呼叫
}
}
// 不同供應商實作介面
class MarketA : Purchase {
override fun buy() { /* 實作 */ }
}
class MarketB : Purchase {
override fun buy() { /* 實作 */ }
}
class Farm : Purchase {
override fun buy() { /* 實作 */ }
}
雖然我們實現了依賴反轉,但這樣的程式碼還是無法執行,因為 purchase
沒有被初始化。需要透過依賴注入(DI)來實現。
class ChefService(
private val purchase: Purchase // 透過建構子注入
) {
fun getIngredients() {
purchase.buy()
}
}
總結
💡 依賴反轉概念:
業務邏輯不應依賴實作細節
兩者應該依賴抽象 (介面)
✨ 優點:
業務邏輯穩定性高
- 實作方式改變時,核心邏輯不需修改
程式靈活
- 可替換不同實作(如:更換供應商)
方便測試
- 可替換測試用的模擬實作
🔑 判斷重點:
實作 = 依賴
介面 = 依賴反轉
下一章依賴注入(之後更新)
Subscribe to my newsletter
Read articles from Sharon Mai directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sharon Mai
Sharon Mai
Hi, I'm Sharon