DDD - 使用聚合的瞬态验证

时间:2013-12-18 02:54:12

标签: c# .net domain-driven-design

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

就目前而言,我创建了一个基本上是空聚合的东西,并设置了地址属性,以便进行检查。基于此,我将返回true或false返回到Web站点(ASP.NET MVC)。这似乎不是DDD背景下的正确方法。

    public bool IsAddressAvailable(string address)
    {
        var aggregate = new Aggregate
                             {
                                 Address = address
                             };
        return aggregate.IsAddressValid();
    }

我有哪些选项可以更好地使用DDD?我考虑将其分成域服务。任何建议将不胜感激!

1 个答案:

答案 0 :(得分:4)

通常,您的聚合不应公开Get-方法,您总是希望遵循Tell-Don't-Ask原则。 如果某些事情需要完成 - 那么你调用一个聚合方法就可以完成它。

但是您通常不想询问Aggregate数据是否有效。特别是如果您已经拥有为您完成此项工作的服务,为什么要将此“验证”与聚合相混合?

经验法则是:

  • 如果Aggregate的行为不需要某些内容,则不需要成为聚合的一部分
  • 您只会将有效数据传递到您的域中。这意味着当您调用聚合行为要求它为您执行某些操作时,您传递的数据已经过验证。您不希望使用数据验证/ if-else分支等污染您的域。保持简单直接。

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

  1. 您不任何事情,不要改变系统的状态。它被认为是一个“读取”操作,直截了当(调用您的服务,对某些表进行验证等)
  2. 您不能依赖验证结果。现在它告诉你“正确”并且在10毫秒内(当你通过网络获得响应,而HTML在浏览器中呈现时等)它已经是历史,它可以随时改变。所以这个验证只是一个指导,不再是。
  3. 因此,如果您只需要“只读”验证,就可以针对您的服务进行验证。 如果您需要验证用户的数据作为操作的一部分,那么在调用域之前(可能在命令处理程序中)执行此操作。 并注意比赛条件(数据库唯一约束可以帮助)。

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