集成事件处理逻辑(业务流程与域逻辑) [英] Integration event handling logic (orchestration vs domain logic)

查看:85
本文介绍了集成事件处理逻辑(业务流程与域逻辑)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,该应用程序通过集成事件在本地跟踪外部文档的状态.某些外部文档类型不共享,而某些则共享.处理诸如 DocumentTypeChanged 之类的外部事件时,我必须执行类似于以下内容的逻辑:

I have an application that tracks the state of external documents locally through integration events. Some external document types aren't shared and some are. When handling an external event such as DocumentTypeChanged I have to execute logic similar to:

internalTypeId = internalDocumentTypeFrom(event.newTypeId);
shared = isSharedType(event.newTypeId);
if (internalTypeId == UNKNOWN && shared) trowMissingSharedDocTypeMappingError();

if (documentTracked(event.documentId)) {
  changeDocumentType(event.documentId, internalTypeId, event.id);

  if (!shared) removeDocument(event.documentId, event.id);
} else if (shared) {
  applicationId = mostRecentApplicationIdOfBn(event.businessNumber)
  attachDocument(applicationId, event.documentId, event.id, ...);
}

总是应该仅根据外部事件对外部文档进行更改,并且 ExternalDocument AR始终保留该文档的最新 externalEventId .

External documents are always supposed to change in reaction to external events only and the ExternalDocument AR always holds onto the latest externalEventId for that document.

我应该在哪里放置以上逻辑?现在,逻辑完全在集成的事件处理程序中,并将诸如 changeDocumentType 之类的命令委托给应用程序的层,但是我觉得大多数BL都已经超出了领域.

Where should I place the above logic? Right now the logic is all in the integration's event handler and delegates commands such as changeDocumentType to the application's layer, but I feel most of the BL is creeping out of the domain.

查看IDDD示例时,大多数集成处理程序,例如

When looking at IDDD samples, most integration handlers such as this one are translating events to application's service layer commands. It's a bit what I currently have, but I feel that poorly communicates the fact that these commands can only happen in reaction to external events.

我的另一个想法是做类似 externalDocumentAppService.handleDocumentTypeChange(externalDocumentId,externalTypeId,externalEventId,bn,发生的事件)的操作,然后该应用程序的服务方法可能类似于:

Another idea I had was to do something like externalDocumentAppService.handleDocumentTypeChange(externalDocumentId, externalTypeId, externalEventId, bn, occurredOn) and then the application's service method may look like:

class ExternalDocAppService {
    handleDocumentTypeChange(externalDocumentId, externalTypeId, externalEventId, bn, occurredOn) {
        internalTypeId = internalDocumentTypeFrom(externalTypeId);
        shared = isSharedType(event.newTypeId);

        document = documentRepository.findByExternalId(externalDocumentId);

        if (document) {
            document.handleTypeChange(internalTypeId, shared, externalEventId, occurredOn);
        } else if (shared) {
            application = caseRepository.mostRecentApplicationOfBn(bn);
            document = application.attachDocument(externalDocumentId, ...);
        }

        if (document) documentRepository.save(document);
    }
}

class ExternalDocument {
    …
    handleTypeChange(internalTypeId, shared, externalEventId, occurredOn) {
        if (internalTypeId == UNKNOWN && shared) trowMissingSharedDocTypeMappingError();

        this.typeId = internalTypeId;
        this.latestExternalEventId = externalEventId;
        this.latestExternalChangeDate = occurredOn;

        if (!shared) this.remove(...);
    }
}

查看代码,应用程序层中仍然会有一些业务逻辑,例如知道忽略新的未共享文档.我们是否可以在这里证明在域服务中提取应用程序的服务逻辑是合理的,在那里应用程序服务将简单地委派给域服务(或多或少)?

Looking at the code there would still be some business logic in the application's layer, such as knowing to ignore new unshared documents. Could we justify extracting the application's service logic in a domain service here, where the application service would simply delegate to the domain service (more or less)?

我也不确定反应式命令名称,例如 handleTypeChange .像 changeTypeBecauseOfExternalTypeChange 这样的东西更合适吗?无论如何,我正在这里寻找一些设计指导……谢谢!

I'm also unsure about reactive command names such as handleTypeChange. Would something like changeTypeBecauseOfExternalTypeChange be more suitable? Anyway, I'm looking for some design guidance here… thanks!

推荐答案

我的建议是引入一个有限状态机,以使检索信息"之间的界限得以确定.和消费信息"很清楚

My suggestion would be to introduce a finite state machine so that the boundary between "retrieving information" and "consuming information" is clear

class ExternalDocAppService {
  handleDocumentTypeChange(externalDocumentId, externalTypeId, externalEventId, bn, occurredOn) {

    // These might belong inside the finite state machine?
    internalTypeId = internalDocumentTypeFrom(externalTypeId);
    shared = isSharedType(event.newTypeId);

    fsm = new FSM(internalTypeId, shared, externalEventId, occurredOn);
    fsm.onDocument(
      documentRepository.findByExternalId(externalDocumentId)
    )

    if (fsm.needsApplication()) {
      fsm.onApplication(
        caseRepository.mostRecentApplicationOfBn(bn)    
      )
    }

    document = fsm.document();
    if (document) documentRepository.save(document);
  }
}

这就是说,处理此事件的过程具有自己的小状态机,以帮助跟踪需要获取哪些信息和需要存储哪些信息.

Which is to say, the process of handling this event has its own little state machine to help keep track of what information needs to be fetched and what information needs to be stored.

请注意,此状态机确实是短暂的东西-它正在管理一些簿记以处理此特定事件.一旦完成,它的状态就可以被丢弃(与我们的域模型中的状态机进行对比,状态机管理着我们的域动态,我们将状态复制到持久性存储中以便以后恢复).

Notice that this state machine is really a short lived thing - it's managing some bookkeeping for the handling of this specific event. Once we're done with it, its state can be thrown away (contrast this with the state machines in our domain model, which are managing our domain dynamics, where we copy the state into our persistence store so that we can resume later).

这篇关于集成事件处理逻辑(业务流程与域逻辑)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆