可扩展的应用架构 – CodeWithAndrea

此可扩展应用架构设计灵感来自 Andrea Bizzotto。此设计的完整文档可以在 这里 找到。此外,您还可以使用名为 Flutter Feature Scaffolding 的VSCode扩展来轻松生成功能文件夹。此设计使用BLoC状态管理解决方案,有关BLoC库的更多信息,我强烈建议您遵循其官方 文档

此项目包含了您立即开始开发高度可扩展的应用程序所需的一切。您也可以将此文件夹结构称为 面向功能(功能内的层) 设计。

关于文件夹结构

    lib/
    ├── src/
    │   ├── common_widgets/
    │   │   └── common_button.dart
    │   ├── constants/
    │   │   └── colors.dart
    │   ├── exceptions/
    │   │   └── routing_exception.dart
    │   ├── features/
    │   │   ├── address/
    │   │   │   ├── data/
    │   │   │   │   ├── datasources/
    │   │   │   │   │   └── address_datasources.dart
    │   │   │   │   ├── models/
    │   │   │   │   │   └── address_model.dart
    │   │   │   │   └── repositories/
    │   │   │   │       └── address_repositories.dart
    │   │   │   ├── domain/
    │   │   │   │   ├── entities/
    │   │   │   │   │   └── address_entities.dart
    │   │   │   │   ├── repositories/
    │   │   │   │   │   └── address_repositories.dart
    │   │   │   │   └── usecases/
    │   │   │   │       └── address_usecases.dart
    │   │   │   └── presentation/
    │   │   │       ├── bloc/
    │   │   │       │   ├── address_bloc.dart
    │   │   │       │   ├── address_event.dart
    │   │   │       │   └── address_state.dart
    │   │   │       ├── pages/
    │   │   │       │   └── address_page.dart
    │   │   │       └── widgets/
    │   │   │           └── address_widgets.dart
    │   │   ├── authentication/
    │   │   │   └── (...)
    │   │   ├── cart/
    │   │   │   └── (...)
    │   │   ├── checkout/
    │   │   │   └── (...)
    │   │   ├── orders/
    │   │   │   └── (...)
    │   │   └── products/
    │   │       └── (...)
    │   ├── localization/
    │   │   ├── app_bn.arb
    │   │   ├── app_en.arb
    │   │   └── localization.dart
    │   ├── routing/
    │   │   └── routing.dart
    │   └── utils/
    │       └── utils.dart
    └── main.dart

您可能会注意到有些文件只是占位符(如api.dart,model.dart)。它们之所以放在那里,只是为了让git能够识别文件夹结构。如果文件夹为空,git将不会对其进行跟踪。由于这主要是一个启动项目,我最初的想法是为您提供标准的文件夹结构。当然,这可能会随着时间的推移而多次更改,不断改进。

为什么选择这种设计模式?

该架构由四个不同的层组成,每一层都包含我们应用程序所需的组件。

➮ presentation: widgets, states, and controllers
➮ application: services
➮ domain: models
➮ data: repositories, data sources,
        and DTOs (data transfer objects)

当然,如果我们只构建一个单页应用,我们可以将所有文件放在一个文件夹中,然后就结束了。?

但一旦我们开始添加更多页面并处理各种数据模型,我们如何以一致的方式组织所有文件呢?

实际上,通常采用 面向功能面向层 的方法。

面向层:缺点

这种方法在实践中易于使用,但随着应用的增长,可扩展性不佳

对于任何给定的功能,属于不同层的不同文件彼此相距很远。这使得处理单个功能变得更加困难,因为我们必须不断在项目的不同部分之间跳转。

如果我们决定要删除某个功能,很容易忘记某些文件,因为它们都是按层组织的。

出于这些原因,当构建中/大型应用程序时,面向功能 的方法通常是更好的选择。

共享代码怎么办?

当然,在构建实际应用时,您会发现您的代码并不总是能像您预期的那样整齐地放入特定的文件夹中。

如果两个或多个独立的功能需要共享某些小部件或模型类怎么办?

在这种情况下,很容易创建名为 sharedcommonutils 的文件夹。

但这些文件夹本身应该如何组织?以及如何防止它们成为所有类型文件的倾倒区?

如果您的应用程序有20个功能,并且只有其中两个功能需要共享一些代码,那么它是否真的应该属于顶级的 shared 文件夹?

如果它被5个功能共享?还是10个?

在这种情况下,没有绝对正确或错误的做法,您必须根据具体情况做出最佳判断。

什么是 feature(功能)?

面向功能不是关于UI!

功能不是用户 看到 的,而是用户 做什么

➮ authenticate
➮ manage the shopping cart
➮ checkout
➮ view all past orders
➮ leave a review

换句话说,功能是 功能性需求,有助于用户 完成给定的任务

并借鉴 领域驱动设计 的一些思路,我决定围绕领域层来组织项目结构。

一旦我明白了这一点,一切就都顺理成章了。我最终得到了您在右侧看到的七个功能区域。

请注意,通过这种方法,给定功能内的代码仍然可以依赖于来自另一个功能The code inside a given feature can still depend on code from a different feature. For example

➮ the product page shows a list of reviews
➮ the orders page shows some product information
➮ the checkout flow requires the user to authenticate first

但我们最终需要共享 跨所有功能 的文件数量大大减少,并且整个结构更加 平衡

如何正确地实现 feature-first(面向功能)?

总而言之,面向功能的方法使我们能够围绕应用程序的功能性需求来构建项目。

因此,这是在您的应用程序中正确使用它的方法:

☞ 从领域层开始,识别模型类和用于操作它们业务逻辑 ☞ 为属于一起的每个模型(或模型组)创建一个文件夹 ☞ 在该文件夹内,根据需要创建 presentationapplicationdomaindata 子文件夹 ☞ 在每个子文件夹内,添加所有您需要的文件

GitHub

查看 Github