遍历聚合

时间:2010-07-02 00:03:53

标签: c# domain-driven-design aggregateroot

围绕域驱动设计进行一些阅读,似乎您应该通过遍历聚合根来访问聚合中的所有实体。

但是,与此同时,您应该尝试封装数据,以便属性/字段受到保护或保密。

因此我的问题是:如果字段受保护/私有,您应该如何遍历聚合?

我现在设置的方式如下:我将我的域模型的所有属性标记为内部,并将“setting”的方法标记为protected。这样,模型外部的任何内容都不能访问属性,但模型中的对象可以访问其他对象属性,我仍然只允许在对象本身内设置属性。

即使我已经这样做了,我仍然觉得这应该只适用于其他聚合实体的属性(我的意思是,客户的“名称”仍然是私有的,但他们的“订单”应该标记为内部允许来自客户的遍历 - >订单 - >等。)

有没有人对此有任何指导?

修改

让我试着为这个问题提供一个更具体的例子: 我的对象图中有两个对象:Bookshelf和Book。让我们说,为了这个例子,Bookshelf是聚合根,并且Books存储在书架上,因此只是聚合中的实体(Bookshelf有一组书籍)。

我想写一个方法来将新书添加到书架。遵循DDD最佳实践,我相信我应该在Bookshelf类上编写一个方法,例如AddBook(Book book)。

但是,如果有业务要求不能将具有相同标题的书籍添加到书架,该怎么办?我想在Bookshelf.AddBook方法中使用一些逻辑来检查书籍的集合,以确保这本书不存在。

现在的问题是我不能这样做,因为我以一种很好的封装方式编写了Book对象,并且它的“Name”属性不能公开访问。

我知道这是一个相当人为的例子,但我希望它能更好地说明问题。我现在也意识到这不仅仅是一个DDD问题,而是现实中的OO封装。我确信必须有一种非常普遍,简单的方法来解决我正在尝试做的事情,而且我正在大力推翻它。

2 个答案:

答案 0 :(得分:2)

在父项及其子项之间存在storng,类似组合的关系的情况下,暴露属性没有任何问题。子属性暴露给父级,但由于它们之间的强关系和相互依赖性,它不会破坏封装。

换句话说,将Book的name属性暴露给Bookshelf没有任何问题,但将Book的名称暴露给其他聚合是错误的(在DDD最佳实践意义上)。揭露可修改的书籍集合也是错误的。应该谨慎地公开只读集合 - 这可能是打破封装的迹象。

这会回答你的问题吗?

答案 1 :(得分:-1)

Visitor pattern是典型的遍历机制。