首页 > 解决方案 > Clean Architecture 中的“用例”是什么?

问题描述

我正在尝试在我正在开发的应用程序中实现 Clean Architecture 结构,但我很难弄清楚到底是什么。

例如,如果我是对的,我的应用程序的实体是Employee, DepartmentEmployeeSkill这些实体还包括所有“验证”逻辑,以确保这些实体是有效的。

用例是我可以对这些实体执行的各种操作吗?

例如,关于的用例Employee

add-employee.js
remove-employee-by-id.js
update-employee-department.js
update-employee-phone-number.js
...and-more-employee-updates.js

这些实际上都是用例吗?

现在addremove我认为没有太多要讨论的,但是更新呢?他们应该是granulated这样吗?

同样使用这样的架构,这是否意味着,如果我想同时更新员工部门和电话号码,我将不得不对数据库进行两次单独的调用,这可以用一个来完成,因为数据库适配器被注入到用例中,每个用例都以“查找”数据库中的实体开始?

标签: javascriptnode.jsclean-architecture

解决方案


暂时推迟考虑实体。通常,您会在尝试根据您的世界心智模型抽象代码时遇到困难,这并没有我们相信的那么有用。

相反,将出于一个原因一起更改的代码耦合到用例中。一个好的开始可以是 GUI 中的每个 crud 操作。新方法、新参数或新类等将是什么不是 CA 模式的一部分,这是您在编写代码时面临的正常权衡的一部分。

我在您的示例中看不到任何实体。在我的代码库中,ContactCard(我在 2021 年的黄页类应用中工作)和 UserContext(安全)是唯一的实体,这两个东西到处都在使用。

其他东西只是数据持有者,而不是真正的实体。我有许多数据持有者的副本,因此未耦合的事物保持非耦合状态。

您的存储库可能应该实现桥接模式。这意味着业务逻辑定义了一些存储库实现的桥梁。该用例不知道数据库表,因此它没有任何细粒度的要求(想想如果它在麦当劳订购食物,它不会说从烤架上我想要 xxx,从油炸锅里我想要 yyy)。

用例对桥接定义要求很高。如此之多,以至于许多存储库最终都有 api 层来导入和管理桥的实现,然后它们适应内部逻辑。

这是业务应用程序中的 api 层与大多数 B2C api 之间的区别。用例的企业 API 正是用例所需要的。

如果您已经被一个虚构的世界模型限制了自己,并决定在其中拆分 repos,而不是根据用例拆分它们,那么您最终的对齐会很差。在多个存储库中拥有相同的 sql 查询或其中的一部分不是问题。随着时间的推移,查询在很多时候看起来都不同,即使它们开始时非常相似。

我会将您的示例用例称​​为 UpdatePhoneNumberEverywhere。然后 UpdatePhoneNumberEverywhereRepository 实现,可以做它想做的事,这是一个细节。用例并不关心。

我可能会做的另一件事是 UpdatePhoneNumber 并且用例接受一个策略。Strategy.CASCADE 或 Strategy.Leaf 等。

就您的表格设计而言,即使它是一个细节,但联系人可能值得被打破。

每个用例都不是从从数据库中查找内容开始的。命令和查询被传入或者你调用它,并且用例做了一些有用的事情。

编写用例最实用的方法是准确实现业务需求所需的内容,针对用例中的公共 api 编写所有测试。只需传入数据作为开始,字典通常就可以了。

当您无法忍受拥有如此多版本的某物时,通常会在以后发现实体,您只需要该某物稳定且始终相同,并且最终用户也期望如此。然后,只需重构。


推荐阅读