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




Compass 应用架构最接近 Flutter 应用架构指南 中描述的 MVVM 架构模式。本案例研究通过 walkthrough Compass 应用的「Home」功能,演示如何落实这些指南。若你不熟悉 MVVM,请先阅读该指南。
Compass 的 Home 屏幕展示用户账户信息与已保存行程列表。从此屏幕可登出、打开行程详情、删除已保存行程,并导航至核心流程首页以规划新行程。
在本案例研究中,你将学习:
-
如何使用 命令模式 在数据变化时安全渲染 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等目录。
本指南推荐的架构适合两者结合:数据层对象(仓库与 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/
大部分应用代码位于 data、domain 与 ui 文件夹。
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 或 riverpod、flutter_bloc、signals
等库实现。层间通信本例全部用方法调用(含轮询新数据),也可用 stream 从仓库向 view model 暴露数据,仍符合本指南规则。
即使完全遵循本指南、不引入额外库,你仍需决策:是否有领域层?若有,如何管理数据访问?答案高度依赖团队需求,没有唯一正确答案。无论如何作答,本指南原则都有助于编写可扩展的 Flutter 应用。
若眯着眼看,一切架构不都是 MVVM 吗?
反馈
#网站本节内容仍在完善中, 欢迎提供反馈!
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-04。查看文档源码 或者 为本页面内容提出建议。