動態

詳情 返回 返回

從字面到本質,用最直白的方式理解依賴倒置原則 - 動態 詳情

從字面到本質,用最直白的方式理解依賴倒置原則(Dependency Inversion Principle, DIP)


一、字面拆解:四個字的含義

  1. 依賴

    • 指代碼中模塊/類之間的使用關係(如A類調用B類的方法)
    • 例如:Service依賴Repository讀寫數據
  2. 倒置

    • 把傳統的依賴方向"反轉"過來
    • 類比:

      • 傳統:高層模塊→直接依賴→底層模塊(如Service→MySQL)
      • 倒置後:高層模塊→依賴抽象←底層模塊實現

二、直觀比喻

場景:手機充電

  • 傳統方式(未倒置):

    手機 → 直接依賴 → 特定充電口(如Lightning接口)  
    (如果換成USB-C,必須改手機硬件)
  • 依賴倒置後

    手機 → 依賴「充電協議」標準 ← USB-C/Lightning實現協議  
    (只要符合協議,接口可以隨意更換)

三、核心思想

  1. 面向接口編程

    • 定義抽象協議(接口)
    • 具體實現必須遵守協議
  2. 控制反轉

    • 高層模塊定義規則(接口)
    • 底層模塊服從規則(實現接口)
  3. 解耦

    修改數據庫(如MongoDB→MySQL)時,  
    業務代碼(Service層)完全不需要改動

四、對比示例

未倒置的代碼:

// 服務層直接依賴具體MySQL實現(危險!)
type UserService struct {
    repo *MySQLUserRepository  // 直接綁定MySQL
}

倒置後的代碼:

// 1. 先定義抽象(領域層)
type UserRepository interface {
    GetUser(id int) (*User, error)
}

// 2. 服務層只依賴抽象
type UserService struct {
    repo UserRepository  // 可以是MySQL/Mongo/任何實現
}

// 3. 具體實現(基礎設施層)
type MySQLUserRepository struct{} 
func (m *MySQLUserRepository) GetUser(id int) (*User, error) {
    // 具體MySQL查詢...
}

五、為什麼叫"倒置"?

傳統分層架構:

       高層模塊
         ↓
       底層模塊

應用DIP後:

       高層模塊
         ↓
       抽象接口 ←─ 底層模塊

依賴方向從自上而下變成了自下而上實現抽象,因此稱為"倒置"。


六、生活案例

未倒置:

你 → 直接依賴 → 某家外賣店的廚師  
(如果換餐廳,你要重新適應)

倒置後:

你 → 依賴「送餐標準」 ← 各餐廳實現標準  
(只要符合送餐標準,換哪家餐廳你都無需改變)

七、關鍵記憶點

  1. 高層制定規則(定義接口)
  2. 底層服從規則(實現接口)
  3. 改動互不影響(解耦)

Add a new 評論

Some HTML is okay.