我正在努力学习DDD。经过数月的学习,我发现建模和编码之间存在矛盾。如您所知,DDD的原则是“Domain 1st,Tech 2nd”。但是,在将实际模型移动到实现中时存在“明确的”约束,例如:
原型:
使用域概念,帖子与多个评论相关联,而评论是依赖于帖子的普通模型。把它移到代码中......
class Post{
Integer postId;
String title;
String content;
String writer;
Collection<Comment> comments;
}
class Comment{
String content;
}
像这样......但如果有数以亿计的评论,就会出现性能问题。根据我调查的解决方案,最后我将原始模型改为如下....
修订模型:
此外,代码也会改变......
class Post{
Integer postId;
String title;
String content;
String writer;
}
class Comment{
Integer postId;
String content;
}
这个修改后的模型对我很有用,我对解决方案很满意。但我觉得有些不一致。似乎该模型由于技术限制而扭曲。如果我们向领域专家展示第一和第二模型并谈论图表,他或她将更好地理解第一个模型。
我对DDD概念有误解吗?如果是这样,请给我一些建议。谢谢。
答案 0 :(得分:4)
域驱动设计带来的思维方式之一就是您的域名会随着您对域名的理解而不断变化。不仅领域会发展,而且你对它的理解和认知也会不断发展。
在我看来,你现在遇到的是试图通过从一个或多个实体如何持久化来加载一个或多个实体来合理化设计。这种共同的父母和孩子的关系感觉很自然,因为这是我们大多数人过去做事的方式。即使从DDD的角度来看,也很容易陷入“没有帖子的评论不存在”的范例。
这归结为您基于域内的数据而不是用例进行建模的事实。以这种方式看待...帖子不仅仅是评论的集合。相反,评论将引用到特定帖子。细微差别听起来微不足道,但它具有广泛的影响。以这种方式建模时,它与您修改过的模型相匹配 - 它完全和完全正常。你唯一需要改变的是你的心态,因为评论可以被认为是一个聚合,就像邮政一样。它们都会有另一个必须存在的用例,但与此同时,你需要看到你不可能做同样的事情,因为它们都是同一个用例的一部分(删除帖子之外) )。
为了说明,请考虑以下用例:
作为一名作家,我希望能够编辑我的帖子的内容。
您的新模型实际上有效地支持了这一点。您正在查看域的使用方式,而不是查看关系。你应该为作家加载评论来编辑吗?在不了解您的域名的情况下,我仍然会认为您不想这样做。有些用例可能涉及帖子和评论,这也没关系。由于在单个有界上下文中有两个聚合,因此您将能够支持仅基于帖子的用例,仅基于注释或两者的组合。
就技术问题而言,您提到“数以亿计的评论”。我认为你的意思是系统范围的,而不是单个帖子?假设您有一个活跃的帖子,并且它在其生命周期中看到了20k条评论。对于正确设计和优化的数据库,这仍然不是问题。当它成为问题时,如果它成为问题,可以通过对所用技术的其他更改来进一步解决,而不是更改域。您可以查看缓存策略(域外,因为这是一个应用程序问题,而不是域关注),外部索引,最终一致性等等。
强烈建议您阅读Vaughn Vernon的“Effective Aggregate Design”系列文章,如果您还没有:
另外,在我看来,他出色的着作“实施领域驱动设计”是必读的。虽然埃文斯的材料是必不可少的,但它更像是理论概念;而弗农材料则讨论了如何将这些概念付诸实践,以及这些决定的含义是什么。
作为附录,就像plalx在下面的评论中指出的那样。这一切都不是一般性的关于帖子和评论的概括,而是明确它们如何适用于您的域名,因为它已经向我们描述了可以从您的模型中推断出什么。帖子和评论可能会对其他人表现不同,因为其他人会有不同的用例。即使在您自己的域中,如果帖子和/或评论存在于不同的上下文中,它们的行为也可能不同。最重要的是,尝试确保添加到域模型(通常)的所有内容都是由于特定的直接用例而添加的。简单地开始数据建模是很诱人的,但是你会发现自己试图强迫用例进入域模型。域建模不应该是有限的过程,也不应该是过程中的单个步骤。愿意并且能够适应对业务随时间改变其整体运营策略的理解或变化的变化。
答案 1 :(得分:0)
我注意到人们进入DDD世界的一个缺陷是,他们也将他们的AR可视化为READ操作的来源。因此,很多时候他们倾向于以“吸引”DTO的方式“模仿”AR及其实体/价值对象,以便为UI提供保湿。
在你的情况下,我会发布一个AR并评论另一个AR。添加注释不应该要求实例化Post。编辑帖子不应该要求“加载”评论。
使用独立的机制将您的帖子/评论投射到POCO / DTO课程中,这样可以在您的帖子中收集评论。
有意义吗?