域驱动设计精确聚合定义

时间:2017-12-17 22:05:47

标签: domain-driven-design ddd-repositories

汇总

聚合是一组关联对象,在数据更改方面被视为一个单元。聚合由边界划分 它将内部物体与外部物体分开。每 Aggregate有一个根。根是一个实体,它是唯一的 物体可从外面进入。

在阅读DDD Quickly这本书时,这是建议的聚合定义。但是,当我解析youtube上的一些视频时,特别是:

DDD& REST - 用于Web的域驱动API - Oliver Gierke

他将汇总定义如下:

Entity + Repository = Aggretate

他还建议我们为每个属性子类化字符串,我认为这有利于DDD解决复杂性的目标。如果我们有100个属性怎么办?

因此,我认为我的问题是双重的。存储库是聚合的一部分,还是仅仅是持久存在属于基础架构层的聚合的工具?其次,提高软件的复杂性和可维护性以实现可读性是否明智,或者这是否有利于整体DDD的目标?

2 个答案:

答案 0 :(得分:1)

  

是聚合

的存储库的一部分

不,完全分开

  

是否存在属于基础架构层的聚合的载体?

也不是这样。

存储库的主要作用是它充当应用程序和数据之间的边界。 blue book引入的存储库中有关集合语义的存储库的原始讨论;如果数据只是存储在内存集合中,那么存储库的接口与您使用的接口相同。

  

第二,提高软件的复杂性和可维护性以实现可读性是否明智,或者这是否有利于整体DDD的目标?

不是“可读性”,而是“沟通”;见blue book

的第2章
  

在没有通用语言的项目中,开发人员必须翻译领域专家....翻译混淆概念,导致代码的破坏性重构......当一个项目的语言断裂时,项目面临严重问题......

在这种情况下,复杂性是从域中获取的复杂性 - 我们可能不应该想象我们可以使用一个或两个域不可知的抽象来模拟具有一千个微妙不同概念的域。

  

你是否认为你认为分类字符串只是为了可读性,尽管它可能导致数百个额外的类是一种谨慎的方法,因为它可以作为共同语言的催化剂

当然不是子类,不。但我建议为每个独特的概念(在域中)使用唯一的名称(在代码中),即使这些概念共享共同的表示。

要选择一个天真的例子,Time不是Money,即使在两者的基础表示都是long的情况下也是如此。

Scott Wlaschin的Domain Modeling Made Functional包含一个扩展示例。有一次,他将验证的电子邮件地址未验证的电子邮件地址模型化为彼此明显不同;即使这两者都有基础字符串表示,他仍然会为每个字符串表示创建单个案例联合类型的步骤,以在代码中捕获这两个概念不能相互替代的事实。

“复杂性”实际上只是将代码工件与域专家无处不在的语言对齐。

现在,根据您编写的Blub,您的代码工件可能会有额外的复杂性来创建这些不同的名称;正如斯科特所说,它在F#中非常直接,但在你平时的工作语言中可能并不那么直接。我的感觉是,如果你选择的语言在你的建模中引入了复杂性,那么你应该首先考虑是否有另一种语言更适合这项任务。

答案 1 :(得分:0)

聚合是关于域的:它代表特定专业领域的主题。

相比之下,存储库是一种关注持久性的技术问题。因此,存储库属于域,它是一个能够使用聚合的实用程序。

所以,不,存储库不属于聚合。您可能也对this question感兴趣了解详细信息。

关于你的第二个问题:这在很大程度上取决于你的应用程序,以及你使用的编程语言...如果你使用动态类型的语言,如JavaScript,你仍然可以做DDD,但你不能够子类的东西(保留ES2015 class关键字,因为它没有将真正的面向对象的编程带到ES)。

除此之外,DDD是一种模拟域名的方法,并允许跨学科团队更好地沟通该域名。 关于技术(当然,除非您的域技术; - )。)。

由于子类化是一个技术问题,因此它与DDD无关。如果有的话,它与如何实现使用DDD创建的模型有关,但这与DDD本身无关。

您可能对Modeling with your team from the wolkenkit documentation感兴趣,它描述了如何进行DDD的方式,以及需要注意的事项。

请注意,我是wolkenkit, a CQRS and event-sourcing framework for Node.js and JavaScript的作者之一。所以请带上一粒盐。