DDD CQRS ES - 域对象现在暴露给表示层?

时间:2013-08-22 21:42:10

标签: dns domain-driven-design cqrs

我的问题很简单 - 在正常的DDD域中,对象不应该暴露给表示层(除了一些人实际上更喜欢它 - 裸体对象如何被称为我相信)。但是CQRS + ES怎么样?写入被委托给封装算法(Events + Sagas),它使用我相信的存储库,然后更新对象调用accept(使用更改的字段/字段)。所以有一些事务逻辑和任何与执行一致性相关的事情......我是对的吗?

1 个答案:

答案 0 :(得分:2)

命令和查询位于您的域之上。您的表示层与此图层对话。

来自我的earlier blogpost

  

命令可以帮助您明确地支持无处不在的语言   在系统边界捕获用户意图 - 考虑使用   案例。您可以将它们视为发送给您的邮件   域。在这方面,它们也可以作为您网域的一层 -   将内部与外部分离,让您逐渐消失   在不破坏外部的情况下在内部介绍概念。该   命令执行程序为您提供了一个可以利用的好管道   集中安全性,性能指标,日志记录,会话   管理等等。

命令代表一个用例。

public class WithdrawMoneyCommand 
{
     public WithDrawMoneyCommand(string account, decimal amount) 
     {
         // Guard and assign here..
     }

     public string Account { get; private set; }

     public decimal Amount { get; private set; }
}

命令由命令处理程序执行。这是您对聚合执行某些操作的地方。无论是调用方法,改变状态,还是播放和录制新事件。事务边界位于命令处理程序级别。

public class WithdrawMoneyCommandHandler : IHandle<WithdrawMoneyCommand> 
{
     public void Handle(WithdrawMoneyCommand command) 
     {
         // Get your account here, and do something with it..
     }
}

这是写方面。

在阅读方面,有人向您发送查询,然后您回复。就这么简单。

public class AccountBalanceReadModel
{
    public string AccountNumber { get; set; }

    public decimal Value { get; set; }
}  

读取模型可以在运行时查询一个或多个聚合。

public class AccountBalanceQuery 
{
     public string AccountNumber { get; set; }
}

public class AccountReads : IHandle<AccountBalanceQuery, AccountBalanceReadModel>
{
    public AccountBalanceReadModel Handle(AccountBalanceQuery query) 
    {
          // Do query or queries and assemble an AccountBalanceReadModel 
    }
}

或(这是事件发挥作用的地方)读取模型已经可以采用您想要的格式,因为它是通过处理事件(由聚合引发)创建的。

public class AccountReads : IHandle<AccountBalanceQuery, AccountBalanceReadModel>
{
    public AccountBalanceReadModel Handle(AccountBalanceQuery query) 
    {
          // Do simple query because your read model is already there in the way you like it
    }
}

回顾如何使用事件创建阅读模型,您可以处理事件并创建阅读模型。

public class AcocuntBalanceReadModelDenormalizer : IHandle<AmountWithdrawn>
{
    public void Handle(AmountWithdrawn @event) 
    {
          // Update your specialized read model here (AccountBalanceReadModel)
    }
}

请注意,事件通常以最终一致的方式处理。这样做的好处是系统的性能和稳定性。