架构案例研究
本指南中的代码示例来自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
| | | |____<共享小部件>
| | |____themes
| |____<功能名称>
| | |____view_model
| | | |_____<视图模型类>.dart
| | |____widgets
| | | |____<功能名称>_screen.dart
| | | |____<其他小部件>
|____domain
| |____models
| | |____<模型名称>.dart
|____data
| |____repositories
| | |____<存储库类>.dart
| |____services
| | |____<服务类>.dart
| |____model
| | |____<api 模型类>.dart
|____config
|____utils
|____routing
|____main_staging.dart
|____main_development.dart
|____main.dart
// test 文件夹包含单元测试和部件测试
test
|____data
|____domain
|____ui
|____utils
// testing 文件夹包含模拟其他类执行测试所需的内容
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 吗?
反馈
#由于本网站的此部分正在不断发展,我们欢迎您的反馈!
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。