我想问一些关于如何避免编写仅仅是数据容器的对象的建议.
请考虑以下聚合根:
public class Post : IAggregateRoot
{
List<Comment> Comments {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
鉴于控制聚合根如何工作的原则,调用上面这样的代码是否有效?
new Post().Comments.Add(New Comment("stuff"));
Run Code Online (Sandbox Code Playgroud)
或者这是正确的方法吗?
public class Post : IAggregateRoot
{
List<Comment> Comments {get; private set;}
public void AddComment(string message)
{
Comments.Add(new Comment(message));
}
}
Run Code Online (Sandbox Code Playgroud)
并且这样称呼:
new Post().AddComment("stuff");
Run Code Online (Sandbox Code Playgroud)
这是Eric Evan意味着Aggregate Roots是原子的吗?
如果是这种情况,是否意味着实体没有任何公共设置者,而是具有支持方法(AddThis,RemoveThat)?这是你如何创建具有丰富行为的对象?
你已经有了聚合根的概念,但你的两个选择实际上是关于实现 - 两者都是有效的.
选项1
优点:您的实体界面仍然非常干净.
缺点:该Add
方法需要逻辑来连接Post
和之间的关系
Comment
(想想NHibernate).您可以创建强类型集合并覆盖Add方法,也可以将事件提升回Post
处理.
选项2
优点:这些Add/Remove
方法为布线逻辑提供了方便的位置.
缺点:随着集合属性数量的增加,您可能会遇到大量Add/Remove
方法.此外,公开的集合必须是ReadOnly,以确保Comments
始终使用特殊方法添加/删除.
我的偏好是选项1 - 我使用引发事件的泛型集合.恕我直言,感觉更自然,其他开发人员更容易编码.虽然SO上的其他人表示不同意.
当我们谈论行为时,我们谈论的是将逻辑附加到实体.例如.如果您想Comments
在5天后停止添加,您会询问Post
添加a Comment
是否有效,并且Post
包含进行检查的逻辑.