架構建議與資源
構建可擴充套件 Flutter 應用的建議。
本頁面介紹了架構最佳實踐、它們的重要性,以及我們是否建議在你的 Flutter 應用中使用它們。請將這些建議視為參考而非死板的規則,你應該根據應用的具體需求進行適配。
本頁面上的最佳實踐設有優先順序,反映了 Flutter 團隊推薦它們的強烈程度。
- 強烈推薦:如果你正在構建一個新應用,應該始終採用此建議。對於現有應用,除非實施該實踐會與你當前的開發方式產生根本性衝突,否則應認真考慮進行重構以採用它。
- 推薦:該實踐很可能會改善你的應用。
- 視情況而定:該實踐在特定情況下可以改善你的應用。
關注點分離
#你應該將應用拆分為 UI 層和資料層。在這些層級內,應進一步按照職責將邏輯拆分到不同的類中。
| 建議 | 描述 |
|---|---|
| 使用明確定義的資料層和 UI 層。 強烈推薦 |
關注點分離是架構最重要的原則。資料層嚮應用的其餘部分公開應用資料,幷包含應用中大部分的業務邏輯。UI 層顯示應用資料並監聽使用者的事件。UI 層包含用於 UI 邏輯和 Widget 的單獨類。 |
| 在資料層使用儲存庫(Repository)模式。 強烈推薦 |
儲存庫模式是一種軟體設計模式,它將資料訪問邏輯與應用的其餘部分隔離開來。它在應用的業務邏輯和底層資料儲存機制(資料庫、API、檔案系統等)之間建立了一個抽象層。在實踐中,這意味著要建立 Repository 類和 Service 類。 |
| 在 UI 層使用 ViewModel 和 View。(MVVM) 強烈推薦
|
關注點分離是架構最重要的原則。這種特定的分離方式使程式碼出錯率大大降低,因為你的 Widget 保持為“啞(dumb)”元件。 |
使用 ChangeNotifier 和 Listenable 來處理 Widget 更新。視情況而定
|
有很多選項可以處理狀態管理,最終的決定取決於個人喜好。閱讀我們的 ChangeNotifier 建議 或 其他熱門選項。 |
| 不要在 Widget 中編寫邏輯。 強烈推薦 |
邏輯應封裝在 ViewModel 的方法中。View 中唯一可以包含的邏輯是:
|
| 使用領域(Domain)層。 視情況而定 |
只有當你的應用具有極其複雜的邏輯,導致 ViewModel 變得臃腫,或者你發現自己在 ViewModel 中重複編寫邏輯時,才需要使用領域層。在超大型應用中,用例(Use-cases)很有用,但在大多數應用中,它們會增加不必要的開銷。 用於具有複雜邏輯需求的應用。 |
處理資料
#謹慎處理資料可以使程式碼更易於理解、減少錯誤,並防止建立格式錯誤或意外的資料。
| 建議 | 描述 |
|---|---|
| 使用單向資料流。 強烈推薦 |
資料更新應僅從資料層流向 UI 層。UI 層中的互動被髮送到資料層進行處理。 |
使用 Command 處理來自使用者互動的事件。推薦
|
Command 可以防止應用中的渲染錯誤,並標準化 UI 層向資料層傳送事件的方式。閱讀 架構案例研究 中關於 Command 的內容。 |
| 使用不可變(Immutable)資料模型。 強烈推薦 |
不可變資料對於確保必要的更改僅發生在正確的地方(通常是資料層或領域層)至關重要。由於不可變物件在建立後無法修改,因此必須建立新例項來反映更改。此過程可防止 UI 層中的意外更新,並支援清晰的單向資料流。 |
| 使用 freezed 或 built_value 生成不可變資料模型。 推薦
|
你可以使用軟體包來幫助生成資料模型中的有用功能,例如 freezed 或 built_value。它們可以生成常見的模型方法,如 JSON 序列化/反序列化、深度相等性檢查和複製方法。如果你有大量的模型,這些程式碼生成包可能會顯著增加應用的構建時間。 |
| 建立單獨的 API 模型和領域模型。 視情況而定 |
使用單獨的模型會增加冗餘,但能防止 ViewModel 和用例中出現複雜性。 用於大型應用。 |
應用結構
#組織良好的程式碼既有益於應用本身的健康,也有益於參與開發該程式碼的團隊。
| 建議 | 描述 |
|---|---|
| 使用依賴注入。 強烈推薦 |
依賴注入可以防止應用擁有全域性可訪問的物件,從而降低程式碼的出錯率。我們建議使用 provider 軟體包來處理依賴注入。 |
| 使用 go_router 進行導航。 推薦
|
Go_router 是 90% 的 Flutter 應用的首選方案。有些特定的用例 go_router 無法解決,在這種情況下,你可以直接使用 Flutter Navigator API 或嘗試 pub.dev 上的其他軟體包。 |
| 使用標準化的類、檔案和目錄命名約定。 推薦
|
我們建議按照架構元件所代表的含義來命名類。例如,你可能會有以下類:
為了清晰起見,我們不建議使用容易與 Flutter SDK 物件混淆的名稱。例如,你應該將共享 Widget 放在名為 |
| 使用抽象 Repository 類 強烈推薦 |
Repository 類是應用中所有資料的真實來源,並促進與外部 API 的通訊。建立抽象 Repository 類允許你建立不同的實現,這些實現可用於不同的應用環境,例如“開發”和“預釋出”。 |
測試
#良好的測試實踐使應用更靈活。它還使得新增新邏輯和新 UI 變得簡單且風險較低。
| 建議 | 描述 |
|---|---|
| 分別測試和組合測試架構元件。 強烈推薦
|
|
| 建立測試用的模擬物件(Fake),並編寫利用模擬物件的程式碼。 強烈推薦
|
模擬物件(Fake)並不關心給定方法的內部工作原理,它們更關心輸入和輸出。如果在編寫應用程式碼時考慮到這一點,你將被迫編寫具有明確輸入和輸出的模組化、輕量級的函式和類。 |
推薦資源
#- 程式碼與模板
- Compass 應用原始碼 - 一個功能齊全、健壯的 Flutter 應用的原始碼,實現了許多這些建議。
- very_good_cli - 由 Flutter 專家 Very Good Ventures 製作的 Flutter 應用模板。該模板生成了類似的應用程式結構。
- 文件
- Very Good Engineering 架構文件 - Very Good Engineering 是 VGV 推出的文件站點,包含技術文章、演示和開源專案。它包括有關架構 Flutter 應用的文件。
- 工具
- Flutter 開發者工具 (DevTools) - DevTools 是用於 Dart 和 Flutter 的一套效能和除錯工具。
- flutter_lints - 一個包含 Flutter 團隊推薦的 Flutter 應用 Lint 規則的軟體包。使用此軟體包可以在團隊中鼓勵良好的編碼實踐。
反饋
#由於本網站的這一部分正在不斷完善中,我們歡迎你的反饋!