对申请结构和沟通方向表示怀疑

时间:2016-07-28 09:43:05

标签: 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. 相对应
  3. QueryService返回' Representation'对象。这些由UI和'Open Host' Facade用作返回值。可以通过Facade将这些对象重用为返回值吗?或者Facade应该创建自己的对象,即使结果基本相同?
  4. ApplicationService需要Commands'作为输入参数。这些Commands是否也被Open Host Facade使用了?或者Facade是否只接受原始值并在委派给Commands时将其转换为ApplicationService
  5. DomainEventHandlers似乎居住在' Infrastructure'层。 ApplicationServiceDomain Service是否也可以订阅Domain Event?或者这总是Infrastructure责任?
  6. 非常欢迎所有建议!

1 个答案:

答案 0 :(得分:2)

  

DomainEventHandler是否可以与Repository对应并在Aggregate上调用某些方法?或者它应该始终与ApplicationService对应吗?

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

  

QueryService返回' Representation'对象。它们由UI和“开放主机”使用。门面作为返回值。这些对象可以被Facade重用为返回值吗?或者Facade应该创建自己的对象,甚至结果基本相同?

有关开放主机服务和应用服务之间差异的讨论here批次。我不清楚谁会使用Open Host服务,或者为什么它存在。

  

ApplicationService需要'命令'作为输入参数。这些命令是否也可以被Open Host Facade使用?或者Facade是否只接受原始值并在委托给ApplicationService时将它们转换为命令?

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

  

DomainEventHandlers似乎驻留在' Infrastructure'层。 ApplicationService或Domain Service是否也可以订阅域事件?或者这始终是基础设施的责任吗?

我一直认为我的处理程序是应用程序服务 - 负责编排用户案例的事情。因此,用例可能是"当收到EventX时,发送电子邮件并更新数据库"。在这个例子中,您可能会考虑发送电子邮件的代码"和#34;保存到数据库的代码"是基础设施关注点,但处理程序本身不会。

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);
    }
}

说实话,我并不是真的从层面思考 - 我更喜欢六角形的建筑风格。在上面的示例中,事件处理程序只会将依赖项注入其中,然后进行业务处理。