1. 核心概念
依賴倒置原則(Dependency Inversion Principle, DIP) 是SOLID原則中的"D",包含兩個關鍵點:
- 高層模塊不應依賴低層模塊,二者都應依賴抽象
- 抽象不應依賴細節,細節應依賴抽象
2. 使用場景
典型應用場景
- 系統需要支持多種實現方式
- 模塊間需要解耦
- 需要進行單元測試(依賴mock對象)
- 系統可能面臨實現方式的變更
反模式示例
class LightBulb: # 低層模塊def turn_on(self):print("Bulb turned on")def turn_off(self):print("Bulb turned off")class Switch: # 高層模塊def __init__(self):self.bulb = LightBulb() # 直接依賴具體實現def operate(self):self.bulb.turn_on()
3. 最佳實踐
正確實現方式
from abc import ABC, abstractmethod# 抽象接口
class Switchable(ABC):@abstractmethoddef turn_on(self):pass@abstractmethoddef turn_off(self):pass# 低層模塊實現接口
class LightBulb(Switchable):def turn_on(self):print("LED bulb turned on")def turn_off(self):print("LED bulb turned off")class Fan(Switchable):def turn_on(self):print("Fan started spinning")def turn_off(self):print("Fan stopped")# 高層模塊依賴抽象
class Switch:def __init__(self, device: Switchable): # 依賴抽象self.device = devicedef operate(self):self.device.turn_on()# 使用示例
bulb = LightBulb()
switch = Switch(bulb)
switch.operate()fan = Fan()
fan_switch = Switch(fan)
fan_switch.operate()
關鍵優點
- 可擴展性:輕松添加新設備類型
- 可測試性:可以創建測試用的mock對象
- 低耦合:Switch類不依賴具體設備實現
- 可維護性:設備實現變化不會影響Switch類
4. Python特有實現方式
使用協議(Protocol)實現
Python 3.8+ 可以使用更靈活的協議實現:
from typing import Protocolclass Switchable(Protocol):def turn_on(self) -> None: ...def turn_off(self) -> None: ...class SmartTV:# 不需要顯式繼承,只需要實現協議方法def turn_on(self):print("TV powered on")def turn_off(self):print("TV powered off")# 同樣可以工作
tv = SmartTV()
tv_switch = Switch(tv)
tv_switch.operate()
5. 實際應用建議
- 適度使用:簡單場景不必過度設計
- 結合DI容器:在大型項目中可使用依賴注入框架
- 接口設計:保持抽象接口小而專注(ISP原則)
- 文檔說明:對抽象接口進行充分文檔說明
6. 常見誤區
? 為每個類都創建接口
? 只為確實需要多實現的模塊創建抽象
? 抽象接口包含太多方法
? 遵循接口隔離原則(ISP)
? 認為DIP就是依賴注入(DI)
? DI是實現DIP的一種技術手段