两个聚合根之间的 DDD 共享实体
DDD shared entity between two aggregate roots
我正在使用两个不同的聚合根:Post 和问题。他们都有一个类别。
到目前为止,我已经将它实现为一个共享实体(我不确定 DDD 中的设计是否正确)。
public class Post
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Question
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Category
{
public int Id { get; private set; }
public string Name { get; private set; }
public string Key { get; private set; }
}
注意:我知道我正在陷入对原始模式的痴迷,并且我计划将原始模式重构为 ValueObjects。
阅读这篇文章后 post DDD: Share entity with multiple aggregate roots 我在想也许我应该将类别转换为 ValueObject(具有多个字段)。
理论上 Category 可以是一个有自己生命周期的 Entity,但现实是我真的 add/remove/update 类别。
是否可以在 DDD 上使用共享实体?或者我最好使用 ValueObject?
让我们先处理一个聚合:Post
现在回答你的问题:
Is it possible to use a shared Entity on DDD? Or I better rather use a ValueObject?
这取决于您将如何处理 类别。
场景一:
您的应用程序中有一个功能(或页面)可以显示一个类别的所有 post。我会采用以下设计:
public class Category
{
public int Id { get; set; }
//this is my in-memory database. Use repository and service to adjust yours
public static List<Post> Posts;
public Category()
{
Posts = new List<Post>();
}
public void AddPost(Guid id, string title, string body)
{
var post = new Post(id, title, body, this.Id);
//saving the post into in-memory. Perhaps you can check some business logic inside Post entity
Posts.Add(post);
}
// You can retrieve all posts of a single category
public IEnumerable<Post> GetAllPosts()
{
return Posts.Where(x => x.CategoryId == this.Id);
}
}
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public int CategoryId { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, int categoryId)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
CategoryId = categoryId;
}
// you can retrieve a post detail
public Post GetPost()
{
return Category.Posts.FirstOrDefault(x => x.Id == this.Id);
}
}
在这种情况下我只能看到一个聚合根:类别。
场景二:
您有 post 页面,用户可以从那里查看详细信息 post。此外,每个 post 都有一个类别,该类别将显示在该详细页面的某处。您可以有以下简单的设计:
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public string CatKey { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, string catKey)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
//I don't even bother with category id. This is a simple value object, you can store all of your categories
//into a hashtable of key-value
CatKey = catKey;
}
// you can retrieve a post detail
public Post GetPost()
{
//get your post detail from repo
}
}
希望你现在能做出决定。
Entity 与 ValueObject 的主要问题是具有相同值的两个 Category 实例是否需要以不同方式进行跟踪?典型的例子是一张美元钞票——在大多数情况下,序列号 (ID) 无关紧要,一美元与另一美元 (ValueObject) 相同。但是,如果您的域正在收集稀有钞票,那将会改变。
我怀疑你的情况不是这样,因为看起来类别实际上只是由名称和键组成。如果 Post 的类别发生变化,您是否需要跟踪以前的类别?
我正在使用两个不同的聚合根:Post 和问题。他们都有一个类别。
到目前为止,我已经将它实现为一个共享实体(我不确定 DDD 中的设计是否正确)。
public class Post
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Question
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Category
{
public int Id { get; private set; }
public string Name { get; private set; }
public string Key { get; private set; }
}
注意:我知道我正在陷入对原始模式的痴迷,并且我计划将原始模式重构为 ValueObjects。
阅读这篇文章后 post DDD: Share entity with multiple aggregate roots 我在想也许我应该将类别转换为 ValueObject(具有多个字段)。
理论上 Category 可以是一个有自己生命周期的 Entity,但现实是我真的 add/remove/update 类别。
是否可以在 DDD 上使用共享实体?或者我最好使用 ValueObject?
让我们先处理一个聚合:Post
现在回答你的问题:
Is it possible to use a shared Entity on DDD? Or I better rather use a ValueObject?
这取决于您将如何处理 类别。
场景一:
您的应用程序中有一个功能(或页面)可以显示一个类别的所有 post。我会采用以下设计:
public class Category
{
public int Id { get; set; }
//this is my in-memory database. Use repository and service to adjust yours
public static List<Post> Posts;
public Category()
{
Posts = new List<Post>();
}
public void AddPost(Guid id, string title, string body)
{
var post = new Post(id, title, body, this.Id);
//saving the post into in-memory. Perhaps you can check some business logic inside Post entity
Posts.Add(post);
}
// You can retrieve all posts of a single category
public IEnumerable<Post> GetAllPosts()
{
return Posts.Where(x => x.CategoryId == this.Id);
}
}
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public int CategoryId { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, int categoryId)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
CategoryId = categoryId;
}
// you can retrieve a post detail
public Post GetPost()
{
return Category.Posts.FirstOrDefault(x => x.Id == this.Id);
}
}
在这种情况下我只能看到一个聚合根:类别。
场景二:
您有 post 页面,用户可以从那里查看详细信息 post。此外,每个 post 都有一个类别,该类别将显示在该详细页面的某处。您可以有以下简单的设计:
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public string CatKey { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, string catKey)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
//I don't even bother with category id. This is a simple value object, you can store all of your categories
//into a hashtable of key-value
CatKey = catKey;
}
// you can retrieve a post detail
public Post GetPost()
{
//get your post detail from repo
}
}
希望你现在能做出决定。
Entity 与 ValueObject 的主要问题是具有相同值的两个 Category 实例是否需要以不同方式进行跟踪?典型的例子是一张美元钞票——在大多数情况下,序列号 (ID) 无关紧要,一美元与另一美元 (ValueObject) 相同。但是,如果您的域正在收集稀有钞票,那将会改变。
我怀疑你的情况不是这样,因为看起来类别实际上只是由名称和键组成。如果 Post 的类别发生变化,您是否需要跟踪以前的类别?