DDD - 使用聚合进行临时验证

Bev*_*van 1 .net c# domain-driven-design

我有一个特定的场景,其中聚合具有检查地址是否有效的行为。此验证是通过网站上的内联 ajax 表单验证在聚合上触发的。在聚合和网站之间是协调两者的应用程序服务。

就目前而言,我创建了一个本质上是空的聚合并设置了地址属性,以便可以完成检查。基于此,我将 true 或 false 返回到网站 (ASP.NET MVC)。在 DDD 的上下文中,这似乎不是正确的方法。

    public bool IsAddressAvailable(string address)
    {
        var aggregate = new Aggregate
                             {
                                 Address = address
                             };
        return aggregate.IsAddressValid();
    }
Run Code Online (Sandbox Code Playgroud)

我有哪些选择可以更好地使用 DDD?我正在考虑将其分离为域服务。任何意见,将不胜感激!

Ale*_*aga 5

通常你的聚合不应该公开Get-方法,你总是想遵循告诉-不要-询问原则。如果有什么东西需要-那么你调用一个聚合方法,它使得它完成。

但是您通常不想询问 Aggregate 数据是否有效。特别是如果您已经有一个服务可以为您完成这项工作,为什么要将这种“验证”与聚合混合使用?

经验法则是:

  • 如果聚合的行为不需要某些东西,则它不需要成为聚合的一部分
  • 您只将有效数据传递到您的域中。这意味着当您调用聚合行为要求它为您做某事时,您传递的数据已经过验证。您不想通过数据验证/if-else 分支等污染您的域。保持简单明了。

在你的情况下,据我所知,你只需要验证用户的输入,所以你不需要打扰你的域,因为两个原因:

  1. 你什么都不,不要改变系统的状态。它被认为是一个“读取”操作,直接操作(调用您的服务,针对某些表进行验证等)
  2. 您不能依赖验证结果。现在它告诉您“正确”,并且在 10 毫秒内(当您通过网络获得响应时,当 HTML 在浏览器中呈现时,等等)它已经成为历史,它可能随时更改。所以这个验证只是一个指导,没有更多。

因此,如果您只需要“只读”验证,只需针对您的服务进行验证。如果您需要在操作过程中验证用户数据,请调用域之前(可能在您的命令处理程序中)执行此操作。并注意赛车条件(DB 唯一约束可以提供帮助)。

您还应该考虑阅读本文以更深入地考虑设置验证:http : //codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/