【发布时间】:2015-11-09 19:14:51
【问题描述】:
我对 DDD 的理念很感兴趣,但我对封装和保护 AggregateRoot 内部实体的概念以及如何引用它们有一些疑问。我创建了一个简单的示例(如果域设计不好,请不要打我,这只是一个澄清问题的示例)。
// can be referenced from outside, is aggregate root
public class Library : AggregateRoot
{
IList<Shelf> shelfs { get; }
}
// can be referenced from outside, is aggregate root
public class Shelf : AggregateRoot
{
Book GetBookById(Guid Id) {...}
}
// should be accessed through Shelf, not referenced outside the context
public class Book : Entity<Guid>
{
Guid Id { get; } // or something else uniqe, e.g. ISBN
}
// how to reference a book here?
// I think, I should not use Id because this is internal and
//only valid for Shelf Aggregate (but I can't have a second one of this book)
public class Lending : AggregateRoot
{
// feels wrong because of passing internals from Shelf
Guid LendedBook { get; set; }
// should I Clone() an object with unique identity, is this allowed in DDD?
Book LendedBook { get; set;}
// create separate type for lending (but what should this type cointain)
LendedBookInfo LendedBook { get; set;}
}
希望得到一个明确的答案,因为大多数示例只是关于 ValueObjects(这很简单,因为它们无论如何都会被复制而没有真正被引用)。 我在示例中使用了 C# 样式的代码,但也欢迎任何其他编程语言或伪代码作为答案。
【问题讨论】:
-
在现实世界的领域中,您很少需要引用其 AR 之外的实体,如果您需要,那么它可能表明该概念不是实体而是 AR 本身。例如,为什么 Book 会在这里成为 Shelf 的实体?不能将一本书移到另一个书架上吗?一本书可能是您的示例域中的 AR,然后您的问题就消失了,因此您的问题的前提有点缺陷。
-
但是,我不认为禁止从其 AR 外部保留实体的 id 引用,只是 id 没有上下文是无用的,因此您还必须保留对 AR id 的引用.另请记住,AR 应仅通过 id 引用其他 AR,并且域模型并不意味着用于 UI 查询和报告。
-
@palx 这个例子设计得不好,因为它不是这里的重点……只是为了说明问题。
-
我知道,这就是我写这些 cmets 的原因。我第二条评论的第一句话回答了你的问题。
标签: entity domain-driven-design aggregateroot design-principles