domain-driven-design - 对应用程序结构和通信方向的疑问

标签 domain-driven-design clean-architecture

我目前正在构建一个 CQS 风格的 DDD 应用程序。我对所有“组件”如何相互协作有些怀疑。

但首先我将简要概述该应用程序的结构:

ApplicationService 
  -> Receives command objects 
  -> doesn't return any results
  -> Acts on Domain model
  -> Speaks with Aggregate repository for domain modifications

QueryService
  -> Bypasses domain model; doesn't speak with Aggregate Repositories
  -> Executes queries against database to populate view
  -> Returns 'Representation' objects

REST Controller
  -> Receives HTTP requests and binds 'body content' & request params to Command objects
  -> delegates to ApplicationService for POST, PUT & DELETE requests
  -> Always returns at least some HTTP code
  -> delegates to QueryService for GET requests

Infrastructure
 -> Handles persistence to DB
 -> Contains some scheduling operations
 -> Handles foreign domain events our domain model is 'interested' in

'Open Host'
  -> This is mainly a Facade to be used by other domains
  -> Facade delegates methods to ApplicationService for domain modifications and to QueryService for data retrieval (bypassing Repositories)


我的问题:

  1. DomainEventHandlerRepository 对应并调用 Aggregate 上的某些方法是否可以?或者它应该始终与 ApplicationService 相对应?
  2. QueryService 返回“Representation”对象。 UI 和'Open Host' Facade 使用这些作为返回值。这些对象可以被 Facade 重用为返回值吗?还是应该Facade创建自己的Object,即使结果基本相同?
  3. ApplicationService 将“Commands”作为输入参数。这些命令也可以被Open Host Facade使用吗?或者,Facade 应该只接受原始值,并在委托(delegate)给 ApplicationService 时将它们转换为 Commands 吗?
  4. DomainEventHandlers 似乎驻留在“基础设施”层。 ApplicationServiceDomain Service 是否也可能订阅 Domain Event?或者这始终是基础设施的责任?

非常欢迎所有建议!

最佳答案

Is it OK that a DomainEventHandler corresponds with a Repository and invokes some methods on a Aggregate? Or should it always correspond with an ApplicationService?

根据我的经验,任何处理程序都是应用程序服务。

QueryService returns 'Representation' objects. These are used by UI AND by 'Open Host' Facade as return value. Is it OK these objects are reused as return value by Facade? Or should Facade create their own Objects, even the results are basically the same?

有很多讨论 here关于开放主机服务和应用程序服务之间的差异。我不清楚谁会使用开放主机服务,也不清楚它为何存在。

ApplicationService takes 'Commands' as input parameters. Is it OK these Commands are also used by the Open Host Facade? Or should the Facade only accept primitive values and convert them to Commands when delegating to ApplicationService?

我会传入应用程序边缘的原语,并将它们转换为命令,然后在应用程序服务中处理

DomainEventHandlers seem to reside on 'Infrastructure' layer. Is it possible that an ApplicationService or Domain Service also subscribes to an Domain Event? Or is this always an Infrastructure responsibility?

我一直认为我的处理程序是应用程序服务 - 负责编排用户案例的东西。因此,用例可能是“收到 EventX 时,发送电子邮件并更新数据库”。在此示例中,您可能会认为“发送电子邮件的代码”和“保存到数据库的代码”是基础设施问题,但处理程序本身不会。

public class ExampleHandler : IHandle<ExampleEvent> 
{
    private IRepository _repo;
    private ISendEmails _emailer;

    public ExampleHandler(Repository repo, ISendEmails emailer)
    { 
        .... set the private fields..
    } 

    public void When(ExampleEvent event) 
    {
        _emailer.Send(event.whatever);
        _repo.Save(something);
    }
}

说实话,我并不真正从层次的角度思考——我更喜欢六边形架构的思维方式。在上面的示例中,事件处理程序只需将依赖项注入(inject)其中,然后就可以开始处理它们的业务。

关于domain-driven-design - 对应用程序结构和通信方向的疑问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38632689/

相关文章:

architecture - 更新 CQRS 中的查询部分

android - Android:组织代码-Retrofit2样板

c# - 在 Clean Architecture 中为 Autofac 实现 Serilog 上下文记录器注入(inject)的正确方法是什么?

microservices - 如何在微服务中使用 Clean Architecture?

java - 我是否需要为 Java 中的所有不可变变量指定 «final» 修饰符?

architecture - 使用 CQRS 进行多对多关系的替代方案

c# - 如何使用 DDD/CQRS 编写功能

c# - 我应该将存储库接口(interface)与域模型分离吗

clean-architecture - 在整洁的架构中创建实体时如何引发实体的域事件

c# - 建模问题(接口(interface)与抽象类)