c# - 我们应该如何在 Clean Architecture 中的层之间传递数据?
问题描述
我一直在阅读 Robert Martin 的“Clean Architecture”,并且一直在努力理解一件事:我们应该如何在“Clean Architecture”中的层之间传递数据?
根据罗伯特马丁的说法:
重要的是,隔离的、简单的数据结构可以跨越边界传递。我们不想欺骗和传递实体对象或数据库行。我们不希望数据结构有任何违反依赖规则的依赖。
如果我理解正确,我们应该始终在层之间传递 DTO。例如,业务逻辑层不应该将域实体返回给 UI 层,它应该将域实体映射到 DTO 并返回它。
同样,业务逻辑层将域实体映射到 DTO 并将其传递给数据访问层,因此数据访问层对域实体一无所知。
这有点吓人,因为我们必须为一个请求执行 8 个映射(4 in -> 和 4 out <-)请看下图。
请注意,图表上的箭头显示的是数据流,而不是依赖关系。
我试图找到好的例子,但它们只会让我感到困惑。例如,某些示例具有直接由数据访问层使用的域实体,因此域实体决定了数据库中表的结构(域实体用作实体框架实体)。
但是如果有一天我决定改变表结构怎么办?这意味着我不仅要在我的数据访问层中进行更改,而且还要在我的业务逻辑层中进行更改。它击败了“插件架构”。
正确的方法是什么?
解决方案
也许它与鲍勃叔叔的干净架构并不完全一致,但这就是我在基于干净架构的项目中跨边界传递数据的方式:
- 从视图到控制器的请求对象 (DTO)
- 从控制器到用例交互器的请求模型 (DTO)
- 域实体到/从存储库
- 从用例交互者到演示者的响应模型 (DTO)
- 从演示者到视图的响应/视图模型 (DTO)
在某些情况下,我作弊并且我的响应模型包含域实体。只要我没有看到严重的问题,我就会保持这种务实的妥协。
这种设置对我来说在几个项目中都很有效。映射的数量利大于弊。域模型仍然独立于持久层,因为从域实体到例如表行的映射可以随时在存储库实现中轻松更改。
推荐阅读
- ios - 如何将数据发布到 CKRecord Fields objc
- ios - 检查自动续订订阅是否仍然有效?斯威夫特 5
- c++ - 如何在课堂上模板化 2D 容器?
- jquery - 为什么角度数据表不呈现?
- android - 信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR)-android 10 (API 29)
- android - 发布前报告,试图从 JVM 回溯追踪 kotlin API 错误
- jquery - 以编程方式触发 jQuery ajax-chosen 的请求/重新加载
- python - Discord.py - 改变状态
- ios - 从设备/相机位置沿 Y 轴命中测试?
- python - 如何从熊猫两列创建共现矩阵?