跳转至正文

架构案例研究

逐步实现 MVVM 架构模式的 Flutter 应用 walkthrough。

本指南代码示例来自 Compass 示例应用,该应用帮助用户规划并预订行程。它是功能、路由与屏幕丰富的健壮示例,与 HTTP 服务器通信,具备开发与生产环境、品牌样式与高测试覆盖率,在多方面模拟真实世界的功能丰富 Flutter 应用。

A screenshot of the splash screen of the compass app.
A screenshot of the home screen of the compass app.
A screenshot of the search form screen of the compass app.
A screenshot of the booking screen of the compass app.

Compass 应用架构最接近 Flutter 应用架构指南 中描述的 MVVM 架构模式。本案例研究通过 walkthrough Compass 应用的「Home」功能,演示如何落实这些指南。若你不熟悉 MVVM,请先阅读该指南。

Compass 的 Home 屏幕展示用户账户信息与已保存行程列表。从此屏幕可登出、打开行程详情、删除已保存行程,并导航至核心流程首页以规划新行程。

在本案例研究中,你将学习:

本案例研究建议按顺序阅读,各页可能引用前文。

案例中的代码示例包含理解架构所需的细节,但并非完整可运行片段。若希望对照完整应用,可在 GitHub 查看。

包结构

#

组织良好的代码便于多人协作、减少冲突,也便于新人浏览理解。代码组织既受益于清晰架构,也反过来强化架构。

组织代码有两种常见方式:

  1. 按功能 — 每个功能所需的类放在一起。例如 auth 目录可含 auth_viewmodel.dartlogin_usecase.dartlogout_usecase.dartlogin_screen.dartlogout_button.dart 等。

  2. 按类型 — 每种架构「类型」放在一起,例如 repositoriesmodelsservicesviewmodels 等目录。

本指南推荐的架构适合两者结合:数据层对象(仓库与 service)不绑定单一功能,UI 层对象(view 与 view model)则绑定功能。 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/// Contains unit and widget tests.
    • data/
    • domain/
    • ui/
    • utils/
  • testing/// Contains mocks that other classes need to execute tests.
    • fakes/
    • models/

大部分应用代码位于 datadomainui 文件夹。 data 按类型组织,因为仓库与 service 可跨功能、被多个 view model 使用。 ui 按功能组织,因为每个功能恰好有一个 view 与一个 view model。

该文件夹结构的其他要点:

  • UI 文件夹还有名为 core 的子目录,包含多 view 共享的 widget 与主题逻辑(如品牌样式按钮)。

  • domain 文件夹包含应用数据类型,供数据层与 UI 层使用。

  • 应用有三个 main 文件,分别作为开发、预发布与生产的入口。

  • lib 同级有两个测试相关目录:test/ 含测试代码,结构与 lib/ 对应;testing/ 是子包,含 mock 等测试工具,可供其他包测试使用。testing/ 可视为不随应用发布的「被测内容」版本。

Compass 应用中还有与架构无关的额外代码。完整包结构请 在 GitHub 上查看

其他架构选项

#

本案例展示一个应用如何遵循推荐架构规则,但也可写出许多其他示例。本应用 UI heavily 依赖 view model 与 ChangeNotifier,也可用 stream 或 riverpodflutter_blocsignals 等库实现。层间通信本例全部用方法调用(含轮询新数据),也可用 stream 从仓库向 view model 暴露数据,仍符合本指南规则。

即使完全遵循本指南、不引入额外库,你仍需决策:是否有领域层?若有,如何管理数据访问?答案高度依赖团队需求,没有唯一正确答案。无论如何作答,本指南原则都有助于编写可扩展的 Flutter 应用。

若眯着眼看,一切架构不都是 MVVM 吗?

反馈

#

网站本节内容仍在完善中, 欢迎提供反馈