Android 依賴注入基礎:概念、原理與實務應用

更新 發佈閱讀 8 分鐘
raw-image
【Android Hilt 依賴注入完整教學】系列文章目錄:連結
Youtube 教學頻道:HKT線上教室

在 Android 開發中,你可能經常聽到「依賴注入」(Dependency Injection,簡稱 DI)這個詞。無論是使用 Dagger、Hilt 或 Koin 等框架,依賴注入都是現代 Android 開發中不可或缺的重要概念。讓我們從零開始,深入淺出地了解什麼是依賴注入,以及為什麼我們需要它。

什麼是依賴注入?

raw-image

讓我們用一個簡單的例子來說明。假設我們有一個 Car 類別,這個類別需要一個引擎(Engine)來運作:

// 未使用依賴注入的寫法
class Car {
private val engine = Engine()

fun start() {
engine.start()
}
}

這時我們就可以說 Car 類別依賴於 Engine 類別。在實際程式開發的過程中經常會遇到,類似的問題,這段程式碼看起來似乎沒什麼問題,但實際上存在一些設計上的缺陷:

  1. Car 類別與 Engine 類別緊密耦合
  2. 難以替換或測試不同類型的引擎
  3. 違反了 SOLID 原則中的開放封閉原則(Open-Closed Principle)

未使用依賴注入的問題

今天假設我們要支援不同類型的引擎,如:純電動車(ElectricEngine)或是油電混合車(HybridEngine),使用上面的寫法就會遇到困難:

// 不好的改法
class Car {
// private val engine = Engine() // 原本的汽油引擎
// private val electricEngine = ElectricEngine() // 改成純電動車
private val hybridEngine = HybridEngine() // 又改成油電混合動力

fun start() {
// engine.start()
// electricEngine.start()
hybridEngine.start()
}
}

這種作法有幾個明顯的缺點:

  1. 每次要改變引擎類型都需要修改 Car 類別的程式碼
  2. 無法同時支援不同類型的引擎
  3. 「透過車子產生引擎」在邏輯上就不合理
raw-image

上述問題的根本原因在於程式碼之間產生了高度耦合 (Coupling) 的情況。為了解決這個問題,我們可以運用控制反轉 (Inversion of Control,IoC)的設計原則,將物件的控制權從物件本身移轉到外部的容器或框架。這樣做可以降低程式碼之間的相依性(Dependency),讓系統更容易維護與擴充。

而依賴注入(Dependency Injection,DI)就是實作控制反轉的一種常見手法。它的概念是在建立物件時,將相依的物件從外部注入進去,而不是讓物件自己產生相依物件。透過這種方式,我們就能達到程式碼解耦 (Decoupling) 的目的。

舉個例子,使用依賴注入的方式,A 類別的建構子可以接收 B 的介面當作參數,IoC 容器在產生 A 的物件實體時,會自動將 B 的物件實體注入進去。如此一來,A 只需要依賴 B 的介面定義,而不需要知道 B 的具體實作細節。

使用依賴注入的改良方案

// 使用依賴注入的寫法
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}

依賴注入的兩種主要方式

  1. 建構子注入(Constructor Injection)
    class Car(private val engine: Engine)
  2. 欄位注入(Field Injection)
    class Car {
    lateinit var engine: Engine
    }

為什麼需要依賴注入?

1. 提高程式碼重用性

使用依賴注入後,我們可以輕鬆替換不同的實作。例如,可以替換成電動引擎:

interface Engine {
fun start()
}

class GasEngine : Engine {
override fun start() { /* 實作汽油引擎啟動邏輯 */ }
}

class ElectricEngine : Engine {
override fun start() { /* 實作電動引擎啟動邏輯 */ }
}

2. 便於測試

在單元測試中,我們可以輕鬆注入模擬物件:

class CarTest {
@Test
fun testCarStart() {
val mockEngine = MockEngine()
val car = Car(mockEngine)
car.start()
// 驗證測試結果
}
}

3. 更容易重構

由於各個元件之間的耦合度降低,重構程式碼變得更加容易。

實際應用案例:ViewModel 中的依賴注入

在 Android MVVM 架構中,ViewModel 經常需要存取 Repository:

// 未使用依賴注入寫法
class ProductViewModel : ViewModel() {
// 傳統寫法會在 ViewModel 內直接建立 Repository 實例
// 超級常見,超耦合寫法,難以替換實作、難以進行單元測試
private val repository = ProductRepository()
private val _products = MutableLiveData<List<Product>>()

fun getProducts() {
val products = repository.getProducts()
_products.value = products
}
}

// 使用依賴注入的寫法
class ProductViewModel(
private val repository: ProductRepository
) : ViewModel() {
private val _products = MutableLiveData<List<Product>>()

fun getProducts() {
val products = repository.getProducts()
_products.value = products
}
}


自動化依賴注入

在大型專案中,手動管理所有依賴關係會變得非常繁瑣。這就是為什麼我們需要依賴注入框架(如 Hilt)的原因。這些框架可以:

  • 自動管理依賴的生命週期
  • 處理依賴之間的關係
  • 提供更簡潔的語法
  • 減少樣板程式碼

結論

依賴注入是一個強大的設計模式,它能夠:

  • 提高程式碼的可重用性
  • 簡化測試流程
  • 使程式碼更容易維護和重構
  • 提供更靈活的架構設計


在接下來的系列文章中,我們將一步一步帶大家由淺入深探討如何在 Android 專案中使用 Hilt 來實現依賴注入!

留言
avatar-img
HKT實驗室
31會員
278內容數
哈囉!歡迎光臨我的沙龍!我是 KT,一位對應用程式開發充滿熱情的開發者。在這個專屬空間,我將與您分享我在應用開發領域的深入學習心得和豐富的實戰經驗。如果您對應用程式開發技術同樣充滿好奇,渴望不斷探索新知,歡迎成為我們的會員,一起在應用程式開發的旅途上,探索更深層次的技術世界,享受學習的樂趣。
HKT實驗室的其他內容
2025/01/27
本文介紹如何在 Android 專案中使用 Hilt Modules,強調其在依賴注入中的重要性。Modules 有助於組織和提供依賴,管理複雜關係,提供介面實作,並控制物件生命週期。將深入探討 Modules 的概念、使用時機與實作方式。
Thumbnail
2025/01/27
本文介紹如何在 Android 專案中使用 Hilt Modules,強調其在依賴注入中的重要性。Modules 有助於組織和提供依賴,管理複雜關係,提供介面實作,並控制物件生命週期。將深入探討 Modules 的概念、使用時機與實作方式。
Thumbnail
2025/01/27
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
Thumbnail
2025/01/27
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
Thumbnail
2025/01/27
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
Thumbnail
2025/01/27
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
Thumbnail
看更多
你可能也想看
Thumbnail
如果你也是那種在職場上追求極致效率,對生活品質有堅持,且渴望一段成熟、穩定、不拖泥帶水關係的專業人士,那麼 Ping! 會是你目前市面上最值得嘗試的選擇。 成熟的大人,不需要在低效的社交中消磨熱情。讓 Ping!,為你的情感生活進行「降噪」,把精力和時間,留給那個真正能與你靈魂共鳴、頻率一致的人。
Thumbnail
如果你也是那種在職場上追求極致效率,對生活品質有堅持,且渴望一段成熟、穩定、不拖泥帶水關係的專業人士,那麼 Ping! 會是你目前市面上最值得嘗試的選擇。 成熟的大人,不需要在低效的社交中消磨熱情。讓 Ping!,為你的情感生活進行「降噪」,把精力和時間,留給那個真正能與你靈魂共鳴、頻率一致的人。
Thumbnail
厭倦只看外貌的交友方式嗎?Ping!主打真實、安全的深度交友體驗,透過真人驗證與多樣化的個人化問答,幫助使用者在認識彼此之前,先理解價值觀、關係期待與交友目標。即使是慢熟的 I 人,也能透過提問找到適合的人選,避免聊到一半才發現方向不同。適合想被理解、重視心理連結與安心互動的你。
Thumbnail
厭倦只看外貌的交友方式嗎?Ping!主打真實、安全的深度交友體驗,透過真人驗證與多樣化的個人化問答,幫助使用者在認識彼此之前,先理解價值觀、關係期待與交友目標。即使是慢熟的 I 人,也能透過提問找到適合的人選,避免聊到一半才發現方向不同。適合想被理解、重視心理連結與安心互動的你。
Thumbnail
Ping!主打真人驗證機制,透過AI人臉比對確保用戶真實性,讓人放心。獨特的照片主題功能、個性化標籤和趣味文字問答,讓用戶更深入展現自我,為開啟話題提供契機,甚至有機會找到擁有相似冷門興趣的同好。Ping!注重高品質的交友關係,透過共同點建立雙方的連結,為現代人提供一個舒適、真實且有意義的交友環境。
Thumbnail
Ping!主打真人驗證機制,透過AI人臉比對確保用戶真實性,讓人放心。獨特的照片主題功能、個性化標籤和趣味文字問答,讓用戶更深入展現自我,為開啟話題提供契機,甚至有機會找到擁有相似冷門興趣的同好。Ping!注重高品質的交友關係,透過共同點建立雙方的連結,為現代人提供一個舒適、真實且有意義的交友環境。
Thumbnail
也許不是我不適合交友,而是我適合的節奏,本來就比較慢。 比起快速認識很多人,我更在意人與人怎麼相遇,才不會那麼累。當對話可以慢慢發生,當我們從想法開始靠近彼此,那種剛剛好的距離,反而讓人更願意走近。
Thumbnail
也許不是我不適合交友,而是我適合的節奏,本來就比較慢。 比起快速認識很多人,我更在意人與人怎麼相遇,才不會那麼累。當對話可以慢慢發生,當我們從想法開始靠近彼此,那種剛剛好的距離,反而讓人更願意走近。
Thumbnail
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
Thumbnail
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
Thumbnail
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
Thumbnail
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
Thumbnail
本篇文章將深入介紹 Android Hilt 依賴注入的基本設定步驟,幫助開發者快速上手這個由 Google 官方推出的相依性注入框架。
Thumbnail
本篇文章將深入介紹 Android Hilt 依賴注入的基本設定步驟,幫助開發者快速上手這個由 Google 官方推出的相依性注入框架。
Thumbnail
本篇文章介紹 Android 開發中的依賴注入(Dependency Injection,DI)概念,強調其在現代開發中的重要性。依賴注入能解決類別之間的緊密耦合問題,提升程式碼的可重用性、測試便利性及重構的容易性。文章中舉例說明了未使用依賴注入的缺陷,並展示了使用依賴注入的改良方案。
Thumbnail
本篇文章介紹 Android 開發中的依賴注入(Dependency Injection,DI)概念,強調其在現代開發中的重要性。依賴注入能解決類別之間的緊密耦合問題,提升程式碼的可重用性、測試便利性及重構的容易性。文章中舉例說明了未使用依賴注入的缺陷,並展示了使用依賴注入的改良方案。
Thumbnail
本文提供全面的 Android Hilt 依賴注入框架完整教學目錄,涵蓋基礎概念、注入方式、進階功能及測試實務。透過這些內容,開發者能夠深入理解並有效學習並運用 Android Hilt 進行依賴注入 Dependency Injection。
Thumbnail
本文提供全面的 Android Hilt 依賴注入框架完整教學目錄,涵蓋基礎概念、注入方式、進階功能及測試實務。透過這些內容,開發者能夠深入理解並有效學習並運用 Android Hilt 進行依賴注入 Dependency Injection。
Thumbnail
本篇文章展示 Android 開發中 Hilt 依賴注入的運用。它基於 Kotlin、Jetpack Compose 等技術搭建,採用 MVVM 架構,利用 Room 存儲數據。Hilt 通過多種注解實現依賴注入,可助學習 Hilt 等多項技術。
Thumbnail
本篇文章展示 Android 開發中 Hilt 依賴注入的運用。它基於 Kotlin、Jetpack Compose 等技術搭建,採用 MVVM 架構,利用 Room 存儲數據。Hilt 通過多種注解實現依賴注入,可助學習 Hilt 等多項技術。
Thumbnail
本篇文章詳細介紹如何在 Android 開發中使用 Dagger 2 進行依賴注入,並提供 GitHub 開源程式碼連結。專案基於 MVVM 架構,採用 Jetpack Compose 構建現代化 UI,展示實際應用中的最佳實踐。
Thumbnail
本篇文章詳細介紹如何在 Android 開發中使用 Dagger 2 進行依賴注入,並提供 GitHub 開源程式碼連結。專案基於 MVVM 架構,採用 Jetpack Compose 構建現代化 UI,展示實際應用中的最佳實踐。
Thumbnail
不管用哪種語言開發軟體,除非是那種一個 function 寫個幾萬行的人 (來人啊,把這種人拖去砍了),不然,一般都會根據某些因素,切割成模組或是特定功能的區塊 (一個 class 或是一個 function),但要完成一個特定功能,這些模組或區塊勢必要一起合作,因此這些模組與區塊就發生了關係。
Thumbnail
不管用哪種語言開發軟體,除非是那種一個 function 寫個幾萬行的人 (來人啊,把這種人拖去砍了),不然,一般都會根據某些因素,切割成模組或是特定功能的區塊 (一個 class 或是一個 function),但要完成一個特定功能,這些模組或區塊勢必要一起合作,因此這些模組與區塊就發生了關係。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News