架構案例研究
一個 Flutter 應用的演練,該應用實現了 MVVM 架構模式。
本指南中的程式碼示例來自 Compass 示例應用程式,該應用程式幫助使用者構建和預訂行程。它是一個功能豐富、包含許多功能、路由和螢幕的健壯示例應用程式。該應用程式與 HTTP 伺服器通訊,具有開發和生產環境,包含特定於品牌的樣式,幷包含高測試覆蓋率。在這些方面以及更多方面,它模擬了一個真實世界、功能豐富的 Flutter 應用程式。




Compass 應用程式的架構最類似於 Flutter 應用架構指南 中描述的 MVVM 架構模式。本架構案例研究透過演練 Compass 應用程式的“主頁”功能來演示如何實施這些指南。如果您不熟悉 MVVM,則應先閱讀這些指南。
Compass 應用程式的主螢幕顯示使用者帳戶資訊和使用者儲存的行程列表。從此螢幕您可以登出、開啟詳細的行程頁面、刪除儲存的行程以及導航到核心應用程式流程的第一頁,該頁面允許使用者構建新的行程。
在本案例研究中,您將學習以下內容
- 如何使用儲存庫和服務在 資料層 中以及在 UI 層 中使用 MVVM 架構模式來實現 Flutter 的 應用架構指南
- 如何使用 命令模式 來安全地渲染資料更改時的 UI
- 如何使用
ChangeNotifier和Listenable物件來管理狀態 - 如何使用
package:provider實現 依賴注入 - 如何 設定測試 以遵循推薦的架構
- 大型 Flutter 應用程式的有效 包結構
本案例研究旨在按順序閱讀。任何給定頁面都可能引用前面的頁面。
本案例研究中的程式碼示例包含理解架構所需的所有詳細資訊,但它們不是完整的、可執行的程式碼片段。如果您希望與完整的應用程式一起使用,可以在 GitHub 上找到它。
包結構
#組織良好的程式碼更容易讓多個工程師在程式碼衝突最少的情況下進行協作,並且更容易讓新工程師導航和理解。程式碼組織既受益於明確定義的架構,也促進了明確定義的架構。
組織程式碼有兩種流行的方法
- 按功能 - 每個功能所需的類組合在一起。例如,您可能有一個
auth目錄,其中包含諸如auth_viewmodel.dart、login_usecase.dart、logout_usecase.dart、login_screen.dart、logout_button.dart等檔案。 - 按型別 - 將每種“型別”的架構組合在一起。例如,您可能擁有諸如
repositories、models、services和viewmodels之類的目錄。
本指南中推薦的架構同時結合了這兩種方法。資料層物件(儲存庫和服務)不與單個功能繫結,而 UI 層物件(檢視和檢視模型)是繫結的。以下是程式碼在 Compass 應用程式中組織的方式。
-
lib/
ui/
core/
ui/
- <shared_widgets>
- themes/
<feature_name>/
view_models/
- <view_model_class>.dart
widgets/
- <feature_name>_screen.dart
- <other_widgets>
domain/
models/
- <model_name>.dart
data/
repositories/
- <repository_class>.dart
services/
- <service_class>.dart
model/
- <api_model_class>.dart
- config/
- utils/
- routing/
- main_staging.dart
- main_development.dart
- main.dart
-
test/// 包含單元和元件測試。
- data/
- domain/
- ui/
- utils/
-
testing/// 包含其他類需要執行測試的模擬物件。
- fakes/
- models/
大多數應用程式程式碼位於 data、domain 和 ui 資料夾中。data 資料夾按型別組織程式碼,因為儲存庫和服務可以在不同的功能中使用,並且可以被多個檢視模型使用。ui 資料夾按功能組織程式碼,因為每個功能恰好有一個檢視和一個檢視模型。
此資料夾結構的其它值得注意的特性
- UI 資料夾還包含一個名為“core”的子目錄。Core 包含由多個檢視共享的小部件和主題邏輯,例如具有品牌樣式的按鈕。
- domain 資料夾包含應用程式資料型別,因為它們由資料和 UI 層使用。
- 該應用程式包含三個“main”檔案,它們充當開發、暫存和生產應用程式的不同入口點。
- 在與
lib同一級別有兩個與測試相關的目錄:test/包含測試程式碼,其自身結構與lib/匹配。testing/是一個子包,包含可以在其他包的測試程式碼中使用的模擬物件和其他測試實用程式。testing/資料夾可以被描述為您的應用程式的一個版本,您不會發布它。它是被測試的內容。
Compass 應用程式中還有一些與架構無關的其他程式碼。有關完整的包結構,請 在 GitHub 上檢視。
其他架構選項
#本案例研究中的示例演示了一個應用程式如何遵守我們推薦的架構規則,但可以編寫許多其他示例應用程式。此應用程式的 UI 嚴重依賴檢視模型和 ChangeNotifier,但也可以使用流或像 riverpod、flutter_bloc 和 signals 包提供的其他庫編寫。此應用程式中層與層之間的通訊使用方法呼叫處理所有內容,包括輪詢新資料。它還可以使用流將儲存庫中的資料暴露給檢視模型,同時仍然遵守本指南中涵蓋的規則。
即使您完全遵循本指南,並且不引入其他庫,您仍然需要做出決定:您是否會有一個域層?如果是,您將如何管理資料訪問?答案在很大程度上取決於單個團隊的需求,因此沒有唯一的正確答案。無論您如何回答這些問題,本指南中的原則都將幫助您編寫可擴充套件的 Flutter 應用程式。
而且,如果您眯起眼睛看,所有架構最終都是 MVVM 嗎?
反饋
#由於本網站的這一部分正在不斷發展,我們 歡迎您的反饋!