如何确定一个对象是否应该是聚合的一部分

时间:2012-02-18 22:01:43

标签: java java-ee domain-driven-design

在我开始阅读有关DDD和聚合的内容后,我似乎试图将所有内容都放入聚合中。几乎每篇博客文章或教程等使用相同的例子都没有任何帮助:订单和订单。

对象可以独立生存是什么意思?这是否意味着它不能在我的域建模中独立存在,或者它是否意味着它不能在现实世界中独立存在?

我正在创建一个用户可以跟踪他们的驾驶的应用程序。喜欢,持续时间,距离等。

我为了对人物进行建模而制作了一个StudentDriver课程,一个DrivingLog用于建模“书籍”,DrivingRecords用于建模每个“行”/记录用户在他/她开车时做出的。这包含持续时间,距离等。

现在的问题是:StudentDriver是否应被视为所有这些类的聚合根,并且每个操作都应通过StudentDriver?或者StudentDriver应该是根,而DrivingLog应该是另一个根,然后StudentDriverDrivingLog会相互关联吗?

听听你的判断会很好吗?在这个例子中也是一般的。

2 个答案:

答案 0 :(得分:3)

DDD是一本很棒的书,我也很喜欢阅读埃文斯关于聚合模式的内容。不过,我觉得你可能会把事情搞得太过分了。

据我了解,Aggregate模式的目的是:

当程序的每个部分与其他所有部分交互时,它变得难以理解(和调试),因为你不能孤立地理解任何一个部分;理解任何一个部分,你必须了解一切。

此外,当交互进入各个方向时,很难找到破坏对象状态的错误,因为你必须到处寻找。如果可以修改某个对象的代码是有限的,那么保证它始终将该对象保持在正确的状态会容易得多。

使用Aggregate模式,您有一个对象,即Aggregate“root”,以及由根“包含”的其他对象。只有根才能“触摸”所包含的对象,这会减少交互可以通过的路径数量。

这是一个有用的想法,在你的概念“工具包”中,但你不需要仅仅为了这样做而使用它。如果“一个对象可以独立生存”而不是担心它意味着什么,那么看看你真正想要用StudentDriverDrivingLog做什么,然后想一想:

如果我允许其他类直接使用DrivingLog,或者如果我要求他们调用StudentDriver上的方法来检索或修改数据,那么这段代码会更简单,更易于管理吗?想象一下代码如何以任何方式读取。在一种情况下,您可能正在从“外部”类编写drivingLog.mileage();在另一方面,你会写studentDriver.loggedMileage()

DDD的最佳观点之一是匹配模型和实现的重要性,甚至包括选择标识符(在您的代码中)这些在实际意义上有意义的事情。与此相协调,您还可以查看代码执行的操作,并思考:如果我考虑这个操作实际代表什么,是对驱动程序或记录日志做了什么?如果实际上操作是为了记录日志而做的,那么就不要使用委托给StudentDriver的{​​{1}}方法,因为你想使用聚合模式。

答案 1 :(得分:0)

聚合是两个具有整体/部分关系的类之间的关系。例如。汽车是完整的,轮子是它的一部分。

在您的情况下,如果属于他,您可以使StudentDriver成为DrivingLog的所有者。如果没有现有学生,则不会保留驾驶记录。因此,DrivingLog不能独立存在。

StudentDriver应该是root用户,并且要注意DrivingLog。但是,DrivingLog不应该知道StudentDriver。(就像单向协作一样)