Domain driven design DDD-聚合根并创建行为对象
我想就如何避免编写仅仅是数据容器的对象征求一些建议 考虑以下聚合根:Domain driven design DDD-聚合根并创建行为对象,domain-driven-design,Domain Driven Design,我想就如何避免编写仅仅是数据容器的对象征求一些建议 考虑以下聚合根: public class Post : IAggregateRoot { List<Comment> Comments {get; set;} } 还是这条路对 public class Post : IAggregateRoot { List<Comment> Comments {get; private set;} public void AddComment(stri
public class Post : IAggregateRoot
{
List<Comment> Comments {get; set;}
}
还是这条路对
public class Post : IAggregateRoot
{
List<Comment> Comments {get; private set;}
public void AddComment(string message)
{
Comments.Add(new Comment(message));
}
}
这就是Eric Evan所说的聚合根是原子的吗
如果是这种情况,是否意味着实体没有任何公共setter,而是有支持方法(AddThis、RemoveThat)?这就是创建具有丰富行为的对象的方式吗?聚合根的概念是正确的,但这两个选项实际上都是关于实现的,而且都是有效的 选项1
- 优点:您的实体接口仍然存在 很干净
- 缺点:
方法需要逻辑 理顺两个部门之间的关系Add
和Post
(思考 NHibernate)。你可以创建一个 强类型集合和 重写Add方法,或者您可以 将事件发回Comment
to 处理Post
- 优点:
方法为布线逻辑提供了方便的位置Add/Remove
- 缺点:随着集合属性数量的增加,添加/删除方法的数量可能会激增。此外,公开的集合必须是只读的,以确保始终使用特殊方法添加/删除
注释
当我们谈论行为时,我们谈论的是将逻辑附加到实体上。例如,如果您想在5天后停止添加
注释
,您将询问帖子
添加注释
是否有效,并且帖子
将包含进行检查的逻辑。我会选择第二个选项
首先,我喜欢将集合显示为IEnumerable。这样,就不可能如此轻松地操纵该列表,并且可以防止不必要的行为。我定期检查对象是否包含在列表中的添加和删除方法
其次,它被封装了,然后我可以添加一些逻辑
最后,您可以通过返回方法本身来使用该方法进行方法链接:
var post = new Post()
.AddComment("My First comment")
.AddComment("My Second comment")
.Publish();
如果AddX方法使实体膨胀过多,则可以使用重载:
var post = new Post()
.Add(new Comment("My First comment"))
.Add(new Comment("My Second comment"))
.Publish();
这两种方法都可能是错误的,除非您有充分的理由将
Post
和Comments
聚集在一起。您试图用大型集群聚合保护哪些业务不变量?如果没有,则Comment
应该是它自己的聚合根。
var post = new Post()
.AddComment("My First comment")
.AddComment("My Second comment")
.Publish();
var post = new Post()
.Add(new Comment("My First comment"))
.Add(new Comment("My Second comment"))
.Publish();