4

试图弄清楚一些概念却无法理解

端口和适配器架构中的用例是什么?

用例的实现会是什么样子?

什么是用例关注点?

它在基础设施或领域中的位置,它说它在应用程序中,那么根据我的理解,应用程序核心和应用程序服务是不同的?

在左侧,适配器依赖于端口并被注入端口的具体实现,其中包含用例。在这一方面,端口及其具体实现(用例)都属于应用程序内部;

https://herbertograca.com/2017/09/14/ports-adapters-architecture/#what-is-a-port

这句话让我很困惑……因为据我了解,主适配器可以是任何要求您的业务逻辑(它对您提供的内容感兴趣)WebAPI、MVC、测试、ConsoleApp。

在左侧,适配器依赖于端口并被注入包含用例的端口的具体实现。

所以我假设它指的是你的业务逻辑被注入让我们说一个 WebApiController 构造函数

在这一方面,端口及其具体实现(用例)都属于应用程序内部;

所以呢 ?这是谁

应用

是 WebApi 吗?还是域?我理解的用例也是我的业务逻辑的实现,所以例如设计会是这样的吗?

Client :
WebApiController(IMyBusinessServicePort service)

Infrastructure :
ImplementingPrimaryAdapter : IMyBusinessServicePort { }
ImplementingSecondaryAdapter : ILoggingPort { }

Domain :
ImplementMyBusinessLogicService : IMyBusinessLogicService 

所以 WebApiController 将使用 ImplementingPrimaryAdapter 提供的实现,而不是我的域中的东西?我不明白

请解释 。

4

3 回答 3

3

六边形架构没有说明六边形的内部结构。

用例适合这样:

驱动程序端口是应用程序的用例边界(六边形)。用例接口将是驱动程序端口。用例的实现将是六边形内的一个类。

Alistair 所说的应用不是 DDD 应用层,而是整个业务逻辑,六边形,与技术解耦。如果您想与 DDD 层进行比较,则必须将六边形分成两层:应用程序和域。ddd 基础设施层将是六边形之外的适配器。

但是六边形架构并没有说明 DDD,它们是不同的东西。如何将 DDD 与六边形架构相匹配取决于您。

如果您想修复这些概念,我已经写了一篇关于六边形架构的文章:

https://jmgarridopaz.github.io/content/hexagonalarchitecture.html

希望能帮助到你。

于 2018-09-13T21:41:36.077 回答
1

领域 :

  1. 端口(将域与基础设施连接起来)
  2. 应用服务
  3. 域服务
  4. 域工厂
  5. 领域实体

基本上,您不会将任何基础设施问题纳入您的领域,而是使用抽象。

基础设施层,任何可能会发生变化的东西,ORM,缓存,日志等......

于 2020-08-01T14:27:45.987 回答
0

根据您是使用基于调用堆栈的编程还是例如 Actor 模型,实现方式存在一些差异。

接下来我讲一个最接近 DDD 和 CQRS 中“C”部分的案例:对系统状态进行更改。“Q”部分在 Hexagon 方面更简单:它的复杂性主要在适配器方面。

至于我,我把词汇放在六边形的核心。它映射到 DDD 通用语言模型,由不可变数据结构组成,并验证这些数据结构上的业务不变量。

接下来,有一个决策点。当你做出决定时,根据单一责任原则,你应该只做这个。不进行外部调用、IO 等。因此,您需要一些信息来做出决定。收集此信息后,可以将 in 包装在 Command 对象中。您将它传递给决策者,该决策者大致映射到 DDD 聚合。然后,它要么批准命令并产生事件或变更集(无论你是否执行 EventSourcing),要么产生拒绝。无需任何外部调用。即它不使用任何Hexagon 的端口。

Hexagon 内部留下的是收集外部数据、调用决策者和处理结果的逻辑。该逻辑可以建模为简单的有限状态机并进行单元测试。这就是我所说的 Hexagon 中的用例。因为这是协调端口和决策者之间数据流动的地方。因此,用例使用端口。

在 Hexagon 的主端口上接收到业务请求后,将创建一个用例实例。有一个 UseCase 的 FSM 和 executor,他们实际调用辅助端口,接收它们的响应并推进用例 FSM。

用例的处理流程可以包括以下步骤:

  • 验证收到的业务请求
  • 如果无效 - 格式错误的业务响应
  • 如果有效 - 准备对辅助端口的请求
  • 发送准备好的请求
  • 接收辅助端口的响应
  • 在失败或超时的情况下 - 格式化带有错误的业务响应
  • 如果数据收集成功,为决策者准备指挥
  • 致电决策者并取回事件/变更集/拒绝
  • 如果被拒绝 - 格式错误的业务请求
  • 如果被接受 - 为辅助端口准备另一组请求以执行决策:持久化到 DB、发送到 MQ、发射火箭等。
  • 等待辅助端口执行请求
  • 如果失败 - 格式化业务响应并出现错误
  • 如果可以 - 成功格式化业务响应

因此,一个用例肯定属于一个域,因为它不依赖于适配器的实现,而是依赖于它们的接口。它形成了一个域的应用层。

将用例放在单独的代码片段中很有用,因为这样代码将有一个更改的原因 - 如果用例发生更改。它不同于决策逻辑或域值验证逻辑。

于 2018-09-14T18:48:41.823 回答