模型层中的领域驱动设计数据库验证

Domain driven design database validation in model layer

我正在为 Twitter 应用程序创建设计以练习 DDD。我的域模型如下所示:

用户和推文标记为蓝色,表示它们是聚合根。在用户和推文之间,我想要一个有界上下文,每个都将在各自的微服务(auth 和 tweet)中 运行。 为了将哪个用户创建了推文而不是 运行 引用到自引用循环中,我创建了 UserInfo 对象。 UserInfo 对象是在创建新用户时通过事件创建的。它仅存储 Tweet 微服务需要用户提供的信息。

当我创建推文时,我只向推文提供用户 ID 和相关字段,使用该用户 ID,我希望能够通过 ID 引用检索 UserInfo 对象,以便在各种子对象中使用它,例如提及和海报。

我运行关注的问题是坚持,乍一看我以为"Just provide the UserInfo object in the tweet constructor and it's done, all the child aggregates have access to it"。但是在 Mention class 上有点难,因为 Mention 将包含一个动态用户名,例如:“@anyuser”。要验证任何用户是否作为 UserInfo 对象存在,我需要查询数据库。但是,我不知道在解析推文的内容之前提到了谁,并且该逻辑驻留在域模型本身中,并且由于使用推文构造函数而被调用。没有这个逻辑,就不会提取任何提及,因此无法验证任何内容 "yet"。

如果我无法在创建推文之前对其进行验证,因为我需要提取逻辑,并且我无法使用域模型层内的数据库存储库,我该如何正确验证提及项?

每当 AR 需要超出其自身边界以收集数据时,有两个主要解决方案:

  1. 您将服务传递给 AR 的方法,使其能够执行解析。服务接口在域中定义,但很可能在基础结构层中实现。

    例如someAr.someMethod(args, someServiceImpl)

    请注意,如果在构建时需要数据,您可能需要引入一个依赖服务接口的工厂,执行验证和 returns AR 实例。

    例如

     tweetFactory = new TweetFactory(new SqlUserInfoLookupService(...));
     tweet = tweetFactory.create(...);
    
  2. 你先在应用层解决依赖,然后传递需要的数据。请注意,应用层可以依赖于域服务,以便首先执行一些反向解析。

    例如

    如果应用层想要解析所有提及的 UserInfo,但不能因为它不知道如何解析文本中的提及,它总是可以依赖域服务或值对象首先执行该任务,然后解析 UserInfo 依赖项并将它们提供给 Tweet AR。不过,请注意不要在应用层泄漏太多逻辑。如果编排逻辑与业务逻辑交织在一起,您可能希望在域服务中提取此类用例处理逻辑。

最后,请注意,任何在 AR 边界之外验证的数据始终被视为陈旧数据。 @xyz 用户当前可能存在,但在发送推文 1 毫秒后不再存在(例如停用)。