跳至主要內容

架構建議和資源

本頁介紹架構最佳實務、它們的重要性,以及我們是否建議將它們應用於您的 Flutter 應用程式。您應該將這些建議視為參考,而非必須遵守的規則,並根據您的應用程式的獨特需求調整它們。

本頁的最佳實務具有優先順序,反映 Flutter 團隊強烈建議的程度。

  • 強烈建議:如果您開始建構新的應用程式,您應該始終實施此建議。您應該強烈考慮重構現有的應用程式以實施此實務,除非這樣做會與您目前的方法產生根本衝突。
  • 建議:此實務可能會改善您的應用程式。
  • 條件性:此實務在某些情況下可以改善您的應用程式。

關注點分離

您應該將應用程式分為 UI 層和資料層。在這些層內,您應該進一步根據職責將邏輯分離到類別中。




建議描述

使用明確定義的資料層和 UI 層。

強烈建議

關注點分離是最重要的架構原則。資料層將應用程式資料暴露給應用程式的其餘部分,並包含應用程式中的大部分業務邏輯。UI 層顯示應用程式資料,並監聽來自使用者的使用者事件。UI 層包含用於 UI 邏輯和 widget 的單獨類別。


在資料層中使用儲存庫模式。

強烈建議

儲存庫模式是一種軟體設計模式,它將資料存取邏輯與應用程式的其餘部分隔離。它在應用程式的業務邏輯和底層資料儲存機制(資料庫、API、檔案系統等)之間建立一個抽象層。在實踐中,這意味著建立 Repository 類別和 Service 類別。


在 UI 層中使用 ViewModels 和 Views。(MVVM)

強烈建議

關注點分離是最重要的架構原則。這種特殊的劃分使您的程式碼更不容易出錯,因為您的 widget 保持「單純」。


使用 ChangeNotifiersListenables 來處理 widget 更新。

條件性

ChangeNotifier API 是 Flutter SDK 的一部分,是一種方便的方式,讓您的 widget 觀察 ViewModels 中的變化。


有許多選項可以處理狀態管理,最終的決定取決於個人偏好。閱讀有關我們的 ChangeNotifier 建議其他熱門選項

不要將邏輯放在 widget 中。

強烈建議

邏輯應該封裝在 ViewModel 的方法中。view 應該包含的唯一邏輯是

  • 簡單的 if 語句,根據 ViewModel 中的標誌或可為 null 的欄位來顯示和隱藏 widget

  • 依賴 widget 計算的動畫邏輯

  • 基於裝置資訊(例如螢幕尺寸或方向)的版面配置邏輯。

  • 簡單的路由邏輯


使用網域層。

條件性

只有當您的應用程式具有過於複雜的邏輯以致塞滿您的 ViewModels,或者您發現自己在 ViewModels 中重複邏輯時,才需要網域層。在非常大型的應用程式中,用例很有用,但在大多數應用程式中,它們會增加不必要的開銷。


在具有複雜邏輯要求的應用程式中使用。


處理資料

小心處理資料使您的程式碼更容易理解,更不容易出錯,並防止建立格式錯誤或意外的資料。





建議描述

使用單向資料流。

強烈建議

資料更新應僅從資料層流向 UI 層。UI 層中的互動會發送到資料層進行處理。


使用 Commands 來處理來自使用者互動的事件。

建議

Commands 可防止應用程式中發生渲染錯誤,並標準化 UI 層向資料層發送事件的方式。閱讀架構案例研究中的 commands。


使用不可變的資料模型。

強烈建議

不可變的資料對於確保資料僅在模型中更新至關重要。


使用 freezed 或 built_value 來產生不可變的資料模型。

建議

您可以使用套件來幫助在您的資料模型中產生有用的功能,例如 freezedbuilt_value。這些可以產生常見的模型方法,例如 JSON ser/des、深層相等性檢查和複製方法。如果您有很多模型,這些程式碼產生套件可能會為您的應用程式增加大量的建置時間。


建立單獨的 API 模型和網域模型。

條件性

使用單獨的模型會增加冗長性,但可以防止 ViewModels 和用例中的複雜性。


在大型應用程式中使用。


應用程式結構

組織良好的程式碼對應用程式本身的健康和處理程式碼的團隊都有好處。




建議描述

使用依賴注入。

強烈建議

依賴注入可防止您的應用程式擁有可全域存取的物件,這使您的程式碼更不容易出錯。我們建議您使用 provider 套件來處理依賴注入。


使用 go_router 進行導覽。

建議

Go_router 是編寫 90% 的 Flutter 應用程式的首選方式。有些特定的用例 go_router 無法解決,在這種情況下,您可以直接使用 Flutter Navigator API 或嘗試在 pub.dev 上找到的其他套件。


針對類別、檔案和目錄使用標準化的命名慣例。

建議

我們建議根據類別所代表的架構元件來命名類別。例如,您可能具有以下類別

  • HomeViewModel
  • HomeScreen
  • UserRepository
  • ClientApiService

為了清楚起見,我們不建議使用可能會與 Flutter SDK 中的物件混淆的名稱。例如,您應該將共享的 widget 放在名為 ui/core/ 的目錄中,而不是放在名為 /widgets 的目錄中。


使用抽象儲存庫類別

強烈建議

儲存庫類別是應用程式中所有資料的真實來源,並促進與外部 API 的通訊。建立抽象儲存庫類別可讓您建立不同的實作,這些實作可用於不同的應用程式環境,例如「開發」和「預備」。



測試

良好的測試實務使您的應用程式具有彈性。它也使新增新邏輯和新 UI 變得簡單且低風險。

建議描述

分別和一起測試架構元件。

強烈建議

* 為每個服務、儲存庫和 ViewModel 類別編寫單元測試。這些測試應單獨測試每個方法的邏輯。

  • 為 view 編寫 widget 測試。測試路由和依賴注入尤其重要。


為測試製作虛擬物件(並編寫利用虛擬物件的程式碼)。

強烈建議

虛擬物件不關心任何給定方法的內部運作,而是關心輸入和輸出。如果您在編寫應用程式程式碼時牢記這一點,您將被迫編寫具有明確定義的輸入和輸出的模組化、輕量型函數和類別。



#
  • 程式碼和範本
    • 羅盤應用程式原始程式碼 - 一個功能齊全、強大的 Flutter 應用程式的原始程式碼,實作了許多這些建議。
    • Flutter 骨架 - 一個 Flutter 應用程式範本,其中包含許多這些建議。
    • very_good_cli - 由 Flutter 專家 Very Good Ventures 製作的 Flutter 應用程式範本。此範本產生類似的應用程式結構。
  • 文件
  • 工具
    • Flutter 開發人員工具 - DevTools 是一套用於 Dart 和 Flutter 的效能和除錯工具。
    • flutter_lints - 一個包含 Flutter 團隊推薦的 Flutter 應用程式 lint 的套件。使用此套件來鼓勵團隊中良好的程式碼編寫實務。

意見反應

#

由於網站的此部分正在發展中,我們歡迎您的意見反應