Clean Architecture + TDD + SOLID + Dependency Injection + GitFlow + Mobx

shopping_app_final_result

Flutter 面试挑战

这个应用是面试过程的一部分。我花了一周的时间完成。我希望你喜欢它,并期待你的反馈。

Flutter 挑战

我们的合作伙伴需要管理他们商店的购物篮,并希望这个解决方案是一个移动应用。

所以,一旦我们知道如何创建 Flutter 移动应用,我们只需要按照以下方式创建它:

  • 应用的第一页将显示产品列表(数据源完全由你决定,可以是后端服务或本地存储,由你决定)。
    • 每个产品都是一个卡片,所有卡片的屏幕展示也由你决定。
    • 每张卡片都有一个添加按钮和一个移除按钮。
    • 该页面还有一个代表购物篮的浮动按钮,显示篮子里的商品数量,如果篮子是空的则不显示数字。
  • 当我们点击浮动按钮时,我们会导航到一个新屏幕,显示篮子里的所有商品,每个商品都由下面的卡片表示。
    • 在购物车页面,我们可以有一个清空购物车的按钮,并自动重定向到产品页面。

开发

现在我将进行开发阶段。

架构

作为开发者,我们知道我们应该为架构而战,因为我是一个人工作,所以这场战斗很短暂。我决定采用 Clean Architecture。原因包括:

  • 由于需求定义不明确,这种架构将确保更改能够轻松应对。
  • 可扩展性将不是问题
  • 易于设置测试
  • 项目开始时无需考虑数据源
  • 项目开始时无需担心状态管理
  • 等等

测试方法

我选择了 TDD(测试驱动开发),因为它非常棒。由于时间限制,我只进行了单元测试。

实体和用例

开发阶段的下一步是定义实体和用例。

实体

  • 购物车
  • CartItem
  • 产品

用例

  • AddItemToCart
  • RemoveItemFromCart
  • GetAllProducts
  • ClearCart
  • RetrieveCart

版本控制

为了版本控制我的代码,我决定使用 Git 和 GitFlow。

依赖注入

为了注入依赖项,我选择了 Get_it,仅仅因为它是我过去使用过的,并且被证明效果很好。

状态管理

我选择了 Mobx,因为有人建议我使用它。在此项目之前,我对这个状态管理解决方案一无所知,这也是为什么我的控制器中存在一些样板代码的原因。

模型图

在完成数据层和领域层并处理完表示层的控制器后,我使用 Figma 创建了一些简单的模型图。

shopping_app_mockups

模型图

UI

在创建模型图后,我创建了我的页面、小部件和组件。然后我将它们与控制器集成。

问题

除了我的控制器中有一些样板代码之外,我还要提到另一个与架构相关的问题。如果不仔细查看源代码,即使仔细看了,您可能也注意不到一个“小问题”。事实是,我在领域层使用了我的 Dtos(我的实体的子类)。问题是领域层不应该知道任何关于数据或表示层的事情。我注意到了这个问题,并决定不解决它(因为时间限制)。

如何解决这个问题

解决方案 1

  • 在领域层创建 Dto 接口。每个 Dto 都应该通过构造函数或函数参数接受其相关的实体。
  • 在数据层实现领域 Dto。
  • 然后,当需要进行 JSON 序列化等操作时,我们应该只使用这些 Dto。

解决方案 2

另一种解决此问题的方法是将 Dto 逻辑直接放在实体中。然而,这种方法会被一些人视为“不规范”。

最终结果

考虑到时间限制,我认为最终结果是可以接受的。你觉得呢?请告诉我。

shopping_app_final_result

GitHub

查看 Github