2026年10月19日 星期一

Dependency Injection 使用時機

Dependency Injection 一個很不錯用的 Design Pattern。

在系統程式或一般的應用程式開發中,只要遇到「需要切換實作」、「需要與外部系統/硬體互動」或「需要進行單元測試(Unit Test)」的情況,都是利用依賴注入(DI)的絕佳時機。

除了你提到的身分驗證(Authentication)外,以下為你整理出最常見且實用的 5 大 DI 應用場景,並依功能類型進行分組:

1. 外部資源與 I/O 存取(最核心的應用)

系統程式經常需要讀寫外部資源,這些資源在開發、測試與實際上線時通常會指向不同的地方,非常適合用 DI 來隔離:

●     資料庫與儲存空間(Repository/Database):

○     情境:程式需要讀取使用者設定檔。

○     DI 的好處:上線時注入連接實際資料庫的 SqlDatabase;測試時則注入一個存取記憶體(In-Memory)或 Mock 資料的 FakeDatabase,避免測試污染真實數據。

●     第三方 API 與網路服務:

○     情境:系統需要發送簡訊(SMS)或 Email 通知。

○     DI 的好處:你可以定義一個 INotificationService。在台灣上線時注入 AWS SNS 或 Twilio 實作;如果遇到特定電信商維護,可以隨時抽換成另一家服務,而不必修改核心商業邏輯。

●     日誌記錄(Logging):

○     情境:系統各個模組都需要記錄錯誤或運行軌跡。

○     DI 的好處:將 ILogger 注入到所有需要寫日誌的類別中。你可以自由決定要把日誌寫到本地檔案(FileLogger)、終端機(ConsoleLogger),還是雲端分析平台(CloudWatchLogger)。

2. 環境與硬體平台切換(系統程式常見)

由於你開發的是系統程式,往往會面臨不同作業系統、環境設定或硬體規格的挑戰:

●     跨平台/硬體架構抽象(Cross-Platform / Hardware Abstraction):

○     情境:你的系統程式需要讀取硬體狀態(如 CPU 溫度、硬碟剩餘空間)。

○     DI 的好處:在 Windows 環境下注入 WindowsSystemMonitor(使用 WMI),在 Linux 環境下注入 LinuxSystemMonitor(讀取 /proc 檔案系統)。

●     設定值管理(Configuration Management):

○     情境:系統在開發(Development)、測試(Staging)和生產(Production)環境有不同的連線字串或加密金鑰。

○     DI 的好處:注入一個 IConfigurationProvider,由它根據目前的環境變數,自動去讀取正確的 .env 檔案、JSON 或是雲端金鑰管理服務(如 AWS Secrets Manager)。

3. 動態策略與演算法抽換(商業邏輯層面)

當系統的某個行為需要根據狀況「動態改變」時,DI 常與策略模式(Strategy Pattern)結合:

●     加密與雜湊演算法(Cryptography):

○     情境:系統需要對敏感資料進行加密,但未來舊演算法可能會被淘汰。

○     DI 的好處:注入 IEncryptionService。今天使用 AesEncryption,幾年後如果安全法規更新,你只需寫一個 QuantumResistantEncryption 並在注入點(Injector)抽換即可。

●     計費、折扣與排程演算法:

○     情境:系統排程需要計算任務的優先權(Priority)。

○     DI 的好處:可以注入不同的 ISchedulerStrategy,像是先進先出(FIFO)或最短任務優先(SJF)。


💡 總結:什麼時候該用 DI?

一個簡單的判斷法則:當一個類別(Class)需要做的事情,牽涉到「控制權不在它手上」的事情時,就應該把那個權力(依賴)注入進來。

這能讓你的系統程式變得像樂高積木一樣,不管是想把認證系統從「帳密」改成「OAuth2/載具認證」,還是要把儲存方式從「本地檔案」改成「雲端資料庫」,都只需要拔掉舊積木、插上新積木即可。

既然你提到了與 agy 合作的 Authentication 系統,如果你感興趣,我們可以:

●     討論如何針對你們目前的認證系統撰寫單元測試(Unit Test),並展示 DI 如何在測試中發揮威力。

●     看看如何把多因素驗證(MFA)或第三方登入作為一種新的依賴,擴充到現有的架構中。



沒有留言:

張貼留言

有 Creational Patterns 的原因,是否是有些狀況不適合直接用 new 建造出一個物件來用?

  沒錯!您的直覺非常準確,這正是整個創建型模式(Creational Patterns)核心要解決的根本問題。 在軟體開發中,直接使用 new 關鍵字來建立物件(例如 MyClass obj = new MyClass(); )雖然直覺又方便,但在中大型系統或需要高度擴充性的...