跳至主要内容

架构建议和资源

此页面介绍了架构最佳实践、其重要性以及我们是否建议将其用于您的 Flutter 应用。您应将这些建议视为建议,而不是一成不变的规则,并且应根据应用的独特需求对其进行调整。

此页面上的最佳实践具有优先级,这反映了 Flutter 团队对其推荐的力度。

  • 强烈推荐:如果您开始构建新的应用程序,则应始终实施此建议。除非这样做会从根本上与您当前的方法冲突,否则您应该认真考虑重构现有应用程序以实施此实践。
  • 推荐:此实践可能会改善您的应用程序。
  • 条件性:此实践在某些情况下可以改善您的应用程序。

关注点分离

您应该将应用程序分为 UI 层和数据层。在这些层内,您应该根据职责进一步将逻辑分离到类中。




建议描述

使用明确定义的数据和 UI 层。

强烈推荐

关注点分离是最重要的架构原则。数据层将应用程序数据公开给应用程序的其余部分,并包含应用程序中的大部分业务逻辑。UI 层显示应用程序数据并侦听来自用户的用户事件。UI 层包含用于 UI 逻辑和小部件的单独类。


在数据层中使用存储库模式。

强烈推荐

存储库模式是一种软件设计模式,它将数据访问逻辑与应用程序的其余部分隔离开来。它在应用程序的业务逻辑和底层数据存储机制(数据库、API、文件系统等)之间创建了一个抽象层。在实践中,这意味着创建存储库类和服务类。


在 UI 层中使用 ViewModel 和 View。(MVVM)

强烈推荐

关注点分离是最重要的架构原则。这种特殊的隔离使您的代码出错的可能性大大降低,因为您的窗口小部件保持“哑巴”状态。


使用ChangeNotifiersListenables处理窗口小部件更新。

条件性

ChangeNotifier API 是 Flutter SDK 的一部分,是让您的窗口小部件观察 ViewModel 中变化的便捷方式。


处理状态管理有很多选项,最终决定权取决于个人喜好。阅读有关我们关于 ChangeNotifier 的建议其他流行选项

不要在窗口小部件中放置逻辑。

强烈推荐

逻辑应封装在 ViewModel 上的方法中。视图中唯一包含的逻辑是

  • 简单的 if 语句,根据 ViewModel 中的标志或可空字段显示和隐藏窗口小部件

  • 依赖于窗口小部件进行计算的动画逻辑

  • 基于设备信息的布局逻辑,例如屏幕尺寸或方向。

  • 简单的路由逻辑


使用领域层。

条件性

仅当您的应用程序具有超过复杂逻辑导致 ViewModel 拥挤,或者您发现自己在 ViewModel 中重复逻辑时才需要领域层。在非常大的应用程序中,用例很有用,但在大多数应用程序中,它们会增加不必要的开销。


用于具有复杂逻辑需求的应用程序。


处理数据

小心处理数据可以使您的代码更易于理解,减少错误,并防止创建格式错误或意外数据。





建议描述

使用单向数据流。

强烈推荐

数据更新应仅从数据层流向 UI 层。UI 层中的交互被发送到数据层进行处理。


使用Commands处理用户交互事件。

推荐

命令可以防止应用程序中出现渲染错误,并规范化 UI 层如何将事件发送到数据层。阅读架构案例研究中的命令。


使用不可变数据模型。

强烈推荐

不可变数据对于确保数据仅在模型中更新至关重要。


使用 freezed 或 built_value 生成不可变数据模型。

推荐

您可以使用包来帮助在数据模型中生成有用的功能,例如freezedbuilt_value。这些可以生成常见的模型方法,如 JSON 序列化/反序列化、深度相等性检查和复制方法。如果您的模型很多,这些代码生成包可能会为您的应用程序增加大量的构建时间。


创建单独的 API 模型和领域模型。

条件性

使用单独的模型会增加冗长性,但可以防止 ViewModel 和用例中的复杂性。


用于大型应用程序。


应用程序结构

组织良好的代码有利于应用程序本身的健康以及处理代码的团队。




建议描述

使用依赖注入。

强烈推荐

依赖注入可以防止应用程序具有全局可访问的对象,这使得您的代码出错的可能性降低。我们建议您使用provider包来处理依赖注入。


使用go_router进行导航。

推荐

Go_router 是编写 90% Flutter 应用程序的首选方法。有一些特定的用例是 go_router 无法解决的,在这种情况下,您可以直接使用Flutter Navigator API或尝试在pub.dev上找到的其他包。


对类、文件和目录使用标准化的命名约定。

推荐

我们建议为它们代表的架构组件命名类。例如,您可能有以下类

  • HomeViewModel
  • HomeScreen
  • UserRepository
  • ClientApiService

为清楚起见,我们不建议使用可能与 Flutter SDK 中的对象混淆的名称。例如,您应该将共享的小部件放在名为ui/core/的目录中,而不是名为/widgets的目录中。


使用抽象存储库类

强烈推荐

存储库类是应用程序中所有数据的真相来源,并促进与外部 API 的通信。创建抽象存储库类允许您创建不同的实现,这些实现可用于不同的应用程序环境,例如“开发”和“登台”。



测试

良好的测试实践使您的应用程序更具灵活性。它还使添加新逻辑和新 UI 变得简单且风险低。

建议描述

分别以及一起测试架构组件。

强烈推荐

* 为每个服务、存储库和 ViewModel 类编写单元测试。这些测试应该单独测试每个方法的逻辑。

  • 为视图编写窗口小部件测试。测试路由和依赖注入尤其重要。


为测试创建模拟(并编写利用模拟的代码)。

强烈推荐

模拟并不像关注给定方法的内部工作原理那样关注输入和输出。如果您在编写应用程序代码时牢记这一点,则您将被迫编写具有良好定义的输入和输出的模块化、轻量级函数和类。



#
  • 代码和模板
    • 指南针应用程序源代码 - 一个功能齐全、强大的 Flutter 应用程序的源代码,它实现了其中许多建议。
    • Flutter 骨架 - 一个包含其中许多建议的 Flutter 应用程序模板。
    • very_good_cli - Flutter 专家 Very Good Ventures 制作的 Flutter 应用程序模板。此模板生成类似的应用程序结构。
  • 文档
  • 工具
    • Flutter 开发者工具 - DevTools 是一套用于 Dart 和 Flutter 的性能和调试工具。
    • flutter_lints - 一个包含 Flutter 团队推荐的 Flutter 应用程序 lint 的包。使用此包可以鼓励团队之间良好的编码实践。

反馈

#

由于本网站的此部分正在发展,我们欢迎您的反馈