【发布时间】:2021-04-07 18:43:38
【问题描述】:
在 DDD 中,Entities 具有 identity 的概念,它可以唯一地标识每个实例,而不管所有其他属性如何。通常这个身份在 Entity 所在的 BC 中必须是唯一的,但也有例外。
有时我们需要创建不仅由根实体和一些值对象创建的聚合,而且还有一个或多个子实体/嵌套实体(我理解为本地实体)。对于这种实体,身份只需在本地是唯一的,即在聚合边界中是唯一的。
鉴于此,我们还要考虑在 DDD 中建模 has-a 关系的两种方式,具体取决于实际业务需求:单独的聚合或聚合根 + 子实体。 p>
在第一种情况下,关系的“子”聚合具有对父级身份的引用,而父级通常有一个工厂方法来创建和返回子级的实例:
class ForumId extends ValueObject
{
// let's say we have a random UUID here
// forum name is not a suitable identifier because it can be changed
}
// "parent" aggregate
class Forum extends AggregateRoot
{
private ForumId _forumId;
private string _name;
method startNewThread(ThreadId threadId, string title): Thread
{
// make some checks, maybe the title is not appropriate for this forum
// and needs to be rejected
...
// passing this forum's ID,
return new Thread(this->_forumId, threadId, title)
}
}
class ThreadId extends ValueObject
{
// let's say we have a random UUID here
// thread title is not a suitable identifier because it can be changed
}
// "child" aggregate
class Thread extends AggregateRoot
{
private ForumId _forumId;
private ThreadID _threadId;
private string _title;
}
如果我们考虑第二种情况,假设由于某些业务原因我们需要将Thread 作为Forum 的本地实体,那么识别它的正确方法是什么? Thread 是否应该仍然包含父 Forum 的 ForumId,或者它是多余的,因为它只会存在于特定的 Forum 中并且永远不会在外部访问?
哪种方式更好,更重要的是为什么?数据模型(即数据库级别)是否可以将决策导向一种或另一种方式,或者我们仍然应该按照良好的 DDD 设计忽略它?
class Forum extends AggregateRoot
{
private ForumId _forumId;
private string _name;
private List<Thread> _threads;
method startNewThread(string title): ThreadId
{
// or use and injected `ThreadIdentityService`'s `nextThreadId(ForumId)` method
var threadId = this.generateNextLocalThreadId()
var newThread = new Thread(/*this->_forumId, */ threadId, title)
this._threads.append(newThread)
return threadId
}
}
// "child" aggregate - case 1
class Thread extends LocalEntity
{
private ForumId _forumId;
private ThreadID _threadId;
private string _title;
}
// "child" aggregate - case 2
class Thread extends LocalEntity
{
private ThreadID _threadId;
private string _title;
}
【问题讨论】:
标签: domain-driven-design entity local identity