【问题标题】:DDD / Aggregate Root / VersioningDDD/聚合根/版本控制
【发布时间】:2017-07-27 22:47:47
【问题描述】:

我们通常如何处理聚合根的版本控制?

我是这么想的(我在调查设计领域)。

进行版本控制的一种方法是使用一种显式方法来创建基于现有版本的新版本。例如,研究(聚合根)。

所以最初我们有一个聚合根,其根实体是 Study,(业务)键为“ABC”,版本为“1”。

通过在 Study 上调用方法“newVersion()”,将创建该 Study 属于同一聚合根的所有其他实体的副本。

所以基本上,版本控制是通过创建一个单独的实例(聚合根)来完成的。 ID 是复合的(业务密钥 + 版本)。

我们如何知道它是否是一个分支?还是只是一个版本? (1.1?或 2)。我想,这个简单的规则会起作用:如果没有关联的其他版本,那么它就是“升级一个版本”(2);如果已经有另一个版本,那么它就是一个分支(1.1)。

另一个问题:噪音。

但这意味着,我们无法处理/修改现有版本。每次我们想对我们的对象进行修改时,我们都必须创建一个 newVersion。每次???嗯....听起来不对。

或者...我们可以根据标志(活动/非活动,或已发布/未发布)制定这样的规则。如果标志为“未激活”,我们可以直接修改 AR,无需创建新版本。如果标志处于活动状态,我们必须:(a)首先将其设置为“非活动”,然后修改....或(b)创建一个新版本并处理该版本(最初设置为“非活动” )。

您想就此事分享任何想法/经验吗?

【问题讨论】:

  • 或者我们可以简单地放弃数字版本,让用户决定版本的名称。反正变化率不高,所以我们可以默认为datestring,YYYYMMDD。唯一性检查可以通过遍历(从当前AR到上一个版本和下一个版本来回遍历)来完成,看看版本名称是否被使用过。它更像是一个标记而不是版本控制。
  • 如果您考虑事件溯源,您将记录所有更改,并且可能不会有明确的版本控制。
  • @cokordaraka 您能否详细说明版本控制概念?您是在建模领域,还是想在战术 ddd 块的概念中添加一些东西,即聚合。不清楚 。版本控制是为了什么?

标签: domain-driven-design versioning aggregateroot


【解决方案1】:

我认为您在研究这个问题时会发现有些混乱,因为有两个非常不同的概念在起作用:

  • 版本控制作为支持乐观并发的并发控制机制
  • 版本控制作为明确的域概念

支持乐观并发的版本控制

乐观并发是允许同时启动两个事务,但如果它们都尝试修改同一个数据项,则只允许第一个事务继续进行。有关不同锁定策略的概述,请参阅 Concurrency Control

总之,您将版本控制留给持久化技术,因为版本的目的是检测对持久层的同时写入。

使用此模式时,通常甚至不保留旧版本的副本,但作为审计跟踪/更改日志当然可以这样做。

版本控制作为一个明确的领域概念

根据您的问题以及支持潜在分支策略的需要,听起来版本控制是您的领域中一个明确的领域概念 - 即“版本”的概念是您的领域专家谈论并与之合作的东西版本是通用语言的重要组成部分。

但是,您提出了一些不同的概念,表明该领域需要进一步探索:

  • 版本分支
  • 用户定义的版本命名/标记(但仍连接到版本“链”)
  • 显式版本更改(用户请求)与隐式版本更改(每次更改自动)
    • 如果我正确理解您的意图,通过显式版本控制,当前的“活动”/“实时”/“提示”版本是可变的,并且可以在不跟踪更改的情况下进行修改,直到用户“提交”它 - 它变得不可变,并创建一个新的可变“实时”版本。

如果您探索此版本,可能会出现一些其他概念:

  • 分支合并(拆分两个分支后,如果要将它们重新组合在一起会怎样?)
  • 回滚 - 如果您有旧版本,是否支持“撤消”一项或多项更改?

鉴于上述情况,您还可以从集中式(例如subversion)和分布式(例如gitmercurial)的版本控制系统的工作方式中找到一些见解,因为它们呈现了一个积极的工作模型:混合了可变和不可变元素的版本跟踪。

此处的未决问题向我表明,您需要与您的领域专家更详细地探讨这一点。使用 DDD 有时很容易迷失在您可以做的事情上,但我强烈建议您尝试并了解自己需要做什么。

您的用户/领域专家如何看待这个世界?他们希望能够进行什么样的操作?这些行动朝着最初目标的目的是什么?您的目标是将这些问题的答案提炼成一个模型,该模型有效地封装了他们使用的过程。

编辑考虑建模

根据您的评论,我的第一反应是在考虑修改后的问卷时质疑对“版本”一词的解释。事实上,我很想挑战模板/调查关系的建模。考虑一组可能的实体:

  • 模板

    • 定义问卷中的问题集
    • 支持操作:
      • 开始调查
      • 修改模板中问题和选项等的各种操作
  • 调查

    • 调查将拥有自己的问卷,而不是引用“实时”模板
    • 当您调用 Template.StartSurvey 时,它会返回一个预填有模板中问题列表的调查
    • 调查还支持修改问题 - 但这不会更改创建它的模板
    • 与模板不同,调查还维护记录的答案列表,并提供设置答案的操作
    • 它可能还包括一个生命周期状态,其中在某些状态下回答问题是允许的,但一旦“提交”就不能修改答案(只是猜测这个)。

在这个世界上,调查从模板中“删除”,然后过着独立的生活。您可以随意修改调查中的问卷,不会影响模板。

这里的权衡是,如果您确实修改了模板,那么已经从它创建的调查都不会更新 - 但听起来这对您来说可能更安全?

您还可以支持将调查转换回模板的操作,这样如果您喜欢修改后的调查的外观,可以将其“模板化”,以便将来用于调查。

【讨论】:

  • 嗨,克里斯,感谢您的全面回答。在我的案例中,版本控制更多的是域概念(我相信)。它来自在调查过程中允许更新问卷(另一个版本)的情况。它不应该在理想情况下发生,但它确实会发生。现在,该调查基于一个模板(因此您不希望在一个调查中切换到另一个版本的调查问卷的决定会影响基于相同模板的其他调查)。根据采样技术的新知识,我仍在绞尽脑汁想出合适的模型。
  • 更新了答案以考虑一些可能有帮助的建模方案。
  • 嗨,克里斯,感谢您的回答。我也是这么想的。我想在这个勇敢的微服务新世界中,我们真的不应该担心复制东西。而关于修改过的模板,可能使用 ES,我们可以设计一种机制来更新“未完成的调查/排队等待的调查”以得到通知,并更新其副本(完全替换)。
猜你喜欢
  • 2016-03-21
  • 2012-02-19
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
相关资源
最近更新 更多