简体   繁体   English

具有洋葱架构的 DDD 端口和适配器,何去何从?

[英]DDD Ports and Adapters with Onion architecture, what goes where?

trying to figure out some concepts and haven't been able to understand试图弄清楚一些概念,但一直无法理解

What is a use-case in the Ports and Adapters architecture ?什么是端口和适配器架构中的用例?

What an implementation of a use-case would look like ?用例的实现是什么样的?

What is a use-case concern ?什么是用例问题?

Where does it fit in the Infrastructure or Domain, it says it goes in the Application, well there is the Application Core and the Application Service which from my understanding are different ?它在基础设施或领域的哪个位置适合,它说它在应用程序中,还有应用程序核心和应用程序服务,我的理解是不同的?

On the left side, the adapter depends on the port and gets injected a concrete implementation of the port, which contains the use case.在左侧,适配器依赖于端口并被注入端口的具体实现,其中包含用例。 On this side, both the port and its concrete implementation (the use case) belong inside the application;在这方面,端口及其具体实现(用例)都属于应用程序内部;

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

This quote confuses me ... because from what I understand a Primary Adapter can be anything that is asking for your business logic (it is interested in what you provide) WebAPI, MVC, Testing, ConsoleApp.这句话让我感到困惑......因为据我所知,主适配器可以是任何要求您的业务逻辑(它对您提供的内容感兴趣)WebAPI、MVC、测试、ConsoleApp。

On the left side, the adapter depends on the port and gets injected a concrete implementation of the port which contains the use case.在左侧,适配器依赖于端口并被注入包含用例的端口的具体实现。

So I assume that it refers to your business logic being injected in let;s say a WebApiController Constructor所以我假设它指的是你的业务逻辑被注入到 let;s 说一个 WebApiController Constructor

On this side, both the port and its concrete implementation (the use case) belong inside the application;在这方面,端口及其具体实现(用例)都属于应用程序内部;

So what ?所以呢 ? who is this这是谁

application应用

Is it the WebApi ?是 WebApi 吗? or is the Domain ?还是域? also the use-case from what I understand is the implementation of my business logic, so for example the design would be something like this ?我所理解的用例也是我的业务逻辑的实现,因此例如设计将是这样的?

Client :
WebApiController(IMyBusinessServicePort service)

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

Domain :
ImplementMyBusinessLogicService : IMyBusinessLogicService 

So WebApiController will use the implementation provided by ImplementingPrimaryAdapter and not something from my domain ?那么 WebApiController 将使用由ImplementingPrimaryAdapter 提供的实现而不是来自我的域的东西? I don;t understand我不明白

please explain .请解释 。

Hexagonal architecture doesn't say anything about the internal structure of the hexagon.六边形架构并没有说明六边形的内部结构。

The use cases fit like this:用例如下:

Driver ports are the use case boundary of the application (the hexagon).驱动程序端口是应用程序的用例边界(六边形)。 A use case interface would be a driver port.用例接口将是驱动程序端口。 The implementation of the use case would be a class inside the hexagon.用例的实现将是六边形内的一个类。

What Alistair call application is not the DDD application layer, is the business logic as a whole, the hexagon, decoupled from technology. Alistair所说的应用不是DDD应用层,是业务逻辑整体,六边形,与技术解耦。 If you want a comparison with DDD layers, the hexagon would have to be splitted in two layers: application and domain.如果要与 DDD 层进行比较,则必须将六边形分为两层:应用程序和域。 The ddd infrastructure layer would be the adapters outside the hexagon. ddd 基础设施层将是六边形外的适配器。

But hexagonal architecture doesn't say anything about DDD, they are different things.但是六边形架构并没有说明 DDD,它们是不同的东西。 It's up to you how to fit DDD with hexagonal architecture.如何将 DDD 与六边形架构相匹配取决于您。

I have written an article about hexagonal architecture, if you want to fix the concepts:我写了一篇关于六边形架构的文章,如果你想修复这些概念:

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

Hope it helps.希望能帮助到你。

Domain :领域 :

  1. ports (which connect the domain with infrastructure)端口(将域与基础设施连接起来)
  2. application services应用服务
  3. domain services域服务
  4. domain factories域工厂
  5. domain entities领域实体

Basically you don't leek any infrastructure concerns into your domain, you use abstractions.基本上,您不会将任何基础架构问题引入您的领域,而是使用抽象。

Infrastructure layer, anything that can be subject to change, ORM, Caching, Logging, etc etc...基础设施层,任何可以更改的东西,ORM,缓存,日志记录等......

There are some differences in implementation, depending on whether you use call-stack based programming or, for example, The Actor Model.实现上存在一些差异,具体取决于您是使用基于调用堆栈的编程还是例如 Actor 模型。

Next I talk about a case that is the closest to DDD and "C" part in CQRS: making changes to a system's state.接下来讲一个最接近CQRS中DDD和“C”部分的案例:改变系统状态。 "Q" part is simpler from the side of Hexagon: its complexity is mostly on the adapter's side.从 Hexagon 的角度来看,“Q”部分更简单:它的复杂性主要在适配器方面。

As for me, I put vocabulary in the core of a Hexagon.至于我,我把词汇放在了 Hexagon 的核心。 It maps to the DDD Ubiquitous Language model and consists of immutable data structures with validation of business invariants on these data structures.它映射到 DDD Ubiquitous Language 模型,由不可变数据结构组成,并在这些数据结构上验证业务不变量。

Next, there is a point of decision making.接下来,还有一个决策点。 When you make a decision, according to Single Responsibility Principle, you should do only this.当你做出决定时,根据单一职责原则,你应该只做这件事。 Not make external calls, IO, etc. So, you need some info to make a decision.不进行外部调用、IO 等。因此,您需要一些信息来做出决定。 When this info is gathered, in can be wrapped in a Command object.收集到此信息后,可以将 in 包装在 Command 对象中。 You pass it to a decision maker, which roughly maps to a DDD aggregate.您将其传递给决策者,后者大致映射到 DDD 聚合。 It then either approves command and produces Event or Changeset (whether you do EventSourcing, or not), or a Rejection.然后它要么批准命令并生成事件或变更集(无论您是否执行 EventSourcing),要么拒绝。 Without any external calls.没有任何外部呼叫。 Ie it doesn't use any Hexagon's ports.即它不使用任何 Hexagon 的端口。

What is left inside a Hexagon is a logic to gather external data, call a decision maker and process result. Hexagon 中剩下的是收集外部数据、呼叫决策者和处理结果的逻辑。 This logic can be modelled as a simple Finite State Machine and unit tested.该逻辑可以建模为一个简单的有限状态机并进行单元测试。 This is what I call a Use Case in my Hexagon.这就是我在 Hexagon 中所说的用例。 Because this is the place, where data flows between ports and decision makers is coordinated.因为这是协调端口和决策者之间数据流动的地方。 So, a Use Case uses Ports.因此,用例使用端口。

A Use Case instance gets created upon receiving of a business request on a Hexagon's primary port.在 Hexagon 的主要端口上收到业务请求时,会创建一个用例实例。 There is a UseCase's FSM and executor, who actually calls secondary ports, receives their responses and advances the use case FSM.有一个用例的 FSM 和执行器,他们实际上调用辅助端口,接收他们的响应并推进用例 FSM。

A Use Case's processing flow can consist of the following steps:用例的处理流程可以包括以下步骤:

  • Validate received business request验证收到的业务请求
  • If invalid - format business response with error如果无效 - 格式化带有错误的业务响应
  • If valid - prepare requests to secondary ports如果有效 - 准备对辅助端口的请求
  • Send prepared requests发送准备好的请求
  • Receive secondary ports' responses接收辅助端口的响应
  • In case of failure or timeout - format business response with error在失败或超时的情况下 - 格式化业务响应错误
  • If data gathered successfully, prepare Command for a decision maker如果数据收集成功,为决策者准备命令
  • Call decision maker and get back Event/Changeset/Rejection呼叫决策者并取回事件/变更集/拒绝
  • If rejected - format business request with error如果被拒绝 - 格式化业务请求并出错
  • If accepted - prepare another set of requests for secondary ports to execute the decision: persist to DB, send to MQ, launch rockets, etc.如果接受 - 为辅助端口准备另一组请求以执行决定:坚持到数据库,发送到 MQ,发射火箭等。
  • Wait for execution of requests by secondary ports等待辅助端口执行请求
  • If failed - format business response with error如果失败 - 用错误格式化业务响应
  • If ok - format business response with success如果没问题 - 成功格式化业务响应

So, a Use Case definitely belongs to a Domain, as it doesn't depend on implementations of adapters, but on their interfaces.因此,用例绝对属于域,因为它不依赖于适配器的实现,而是依赖于它们的接口。 And it forms a Domain's application layer.它形成了一个域的应用层。

It is useful to put a Use Case in a separate fragment of code, because this way this code would have a single reason to change - if, well, the use case changes.将用例放在单独的代码片段中很有用,因为这样该代码将有一个更改的原因 - 如果用例发生更改。 It is distinct from decision making logic or from Domain Values validation logic.它不同于决策逻辑或域值验证逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM