【问题标题】:In Clean Architecture design, Do we need to create a separate "Project" for each layer?在 Clean Architecture 设计中,我们是否需要为每一层创建一个单独的“项目”?
【发布时间】:2021-08-20 08:44:03
【问题描述】:

在 Clean Architecture 设计中,我们是否需要为每一层创建一个单独的“项目”?或者我们可以在同一个项目中定义具有文件夹和命名空间的层吗?

我正在使用 Net Core 在微服务架构中设计一个新应用程序。我打算在我的设计中使用清洁架构原则。

我计划为我的每项服务使用以下项目结构。这是正确的方法吗?我正在尝试减少项目数量。

  • 项目 1 - 演示文稿
  • 项目 2 - 应用层、域层、持久层(此处 层由文件夹和命名空间隔离)
  • 项目 3 - 基础设施
  • 项目 4 - 横切

【问题讨论】:

  • "被文件夹和命名空间隔离" -> 没有这样的东西。同一个程序集中的类都可以互相看到并互相交谈。您提到的“隔离”在解决解决方案时对您来说是完全可见的。
  • 人们会滥用“按文件夹分离”(在单体组件中)......毫无疑问。虽然理论上可以做到,但它永远不会发生。人们将“跳过/跳过”数据层的业务层......只要对他们来说变得更容易一点。通过使用不同的cs projs来保护分层的完整性。又名,打破你的项目#2。开始一个新项目非常容易。稍后尝试修复它..头疼。
  • 我同意卡米洛的观点。这是一个(非常糟糕的)“社会契约”。

标签: .net asp.net-core microservices software-design clean-architecture


【解决方案1】:

在开发初期,将所有内容放在一个地方似乎更好,但随着项目的发展,您将越来越难以维护单独组件的概览。

发生这种情况时,您可以决定移动代码,但这可能比一开始就分离代码更麻烦。

尤其是当您开始考虑使用 nuget 包等时,这可以帮助您确定哪些代码使用了哪些组件。

【讨论】:

  • 同意并点赞。一开始多花一点时间可以避免以后的麻烦。
【解决方案2】:

我强烈建议你真的拥抱

关注点分离

软件设计负责人。

正如我的评论所说,一个新项目的“文件夹分离”基本上是在乞求一个“大泥球”软件项目。

在新项目中添加层(csprojs)非常简单。不这样做是非常非常短视的。

一般来说,如果有疑问,请选择“过度分离”。为什么?稍后“组合”的琐碎。巨大的头痛和“以后分开”的努力。

我的典型设置。

./src/BusinessServices/Optum.Flex.MyProject.BusinessServices.csproj
    WebApi Layer.  (and top layer for IoC "Compositon Root").  References everything below, except unit tests.

./src/BusinessLogic/Optum.Flex.MyProject.BusinessLogic.csproj
  Business Logic.  References Optum.Flex.MyProject.DomainDataLayer.Interfaces.csproj.  and Domain.csproj.  DOES NOT REFERENCE concrete EntityFramework.csproj.


./src/DomainDataLayer.EntityFramework/Optum.Flex.MyProject.DomainDataLayer.EntityFramework.csproj
  Concrete DomainDataLayer.  References Optum.Flex.MyProject.DomainDataLayer.Interfaces.csproj.  and Domain.csproj.  
  Will also contain Orm-Entites, Orm-Maps.
  Can also contain the "converters" from Orm-Entities to DTOS(pocos) and vice versa.  (Use mapster or automapper or hand map)

./src/DomainDataLayer.Interfaces/Optum.Flex.MyProject.DomainDataLayer.Interfaces.csproj
    Interfaces for DomainDataLayer.  
    The interfaces accept and return Domain objects, the DTOS/POCOS.

./src/Domain/Optum.Flex.MyProject.Domain.csproj
    DTOS (or POCOS).  Has ZERO REFERENCES TO ANY OTHER LIBRARY.  Simple Pocos/Dtos.


./src/UnitTestProjects/UnitTests.EntityFramework/UnitTests.EntityFramework.csproj
./src/UnitTestProjects/UnitTests.BusinessLogic/UnitTests.BusinessLogic.csproj
./src/UnitTestProjects/UnitTests.Domain/UnitTests.Domain.csproj

我走得更远。

CQSP(命令查询分离主体)

https://martinfowler.com/bliki/CQRS.html

不要从其他服务“跨线”传递 ORM 实体。

https://thorben-janssen.com/dont-expose-entities-in-api/

这些问题以及由此引发的所有讨论主要有两个原因: 实体是 POJO。看起来它们通常可以很容易地序列化和反序列化为 JSON 文档。如果它真的那么容易工作,那么您的 REST 端点的实现将变得非常简单。 暴露你的实体会在你的 API 和你的持久性模型之间建立一个强耦合。两种模型之间的任何差异都会带来额外的复杂性,您需要找到一种方法来弥合它们之间的差距。不幸的是,您的 API 和持久性模型之间总是存在差异。最明显的是处理实体之间的关联。

https://jacquessmuts.github.io/post/modularization_room/

不要这样做。请。它打破了实现适当关注点分离的项目所要求的信息隐藏的核心概念。 映射您的实体 相反,您应该有两个不同的对象。您应该一个代表数据库实体(Orm-Entity)的对象(Java 这是 JPA Annotated Object,C# 这是 Orm-Attributed 对象(不太推荐)或 FluentMapped Orm-Entity)和一个对象(“Dto”或“Poco”)用于传递纯数据。您的数据库模块应该是唯一导入 Room 库的模块。如果任何其他模块导入了数据库模块的那些实现细节,那么您就不是应有的信息隐藏。

这个面包屑到“组合根”

https://blog.ploeh.dk/2011/07/28/CompositionRoot/

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 2016-04-24
    相关资源
    最近更新 更多