2010-07-02 116 views
2

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

但是,在同一时间,你应该真正尝试和封装你的数据,使属性/字段是保护或私人。

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

我现在设置它的方式如下所示:我将我的域模型的所有属性标记为内部,并将“设置”标记为受保护的方法。这样,模型外部至少没有任何东西可以访问属性,但模型中的对象可以访问其他对象属性,我仍然只允许从对象本身中设置属性。

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

有没有人有任何指导呢?

编辑:

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

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

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

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

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

回答

2

父母与子女之间存在暴力,暴露属性没有任何错误。儿童财产暴露于父母,但由于他们之间的密切关系和相互依存关系,它不会破坏封装。

换言之,向Bookhelf公开Book的名称属性没有任何错误,但是将Book的名称暴露给其他聚合是错误的(根据DDD最佳实践)。揭露可修改的书籍集合也是错误的。公开只读集合时应谨慎 - 它可能是破解封装的标志。

这是回答您的问题吗?

+0

它确实回答了这个问题,我想我的意思是说我正在反思它 - 这很简单,只需稍微放松规则并让财产可用,但只能在总计中使用。 出现的问题是,您将使用哪种C#语言功能来允许访问该书的名称到书架,但不允许访问该集合以外的类? (根据一个c#汇编中的一个有限上下文的不同聚合来思考它) – Justin 2010-07-03 08:04:43

-1

Visitor pattern是典型的遍历机制。

+0

这不是我认为在这里的遍历类型。访问者模式让我遍历对象图并对图的每个节点执行一个操作。但是,我只是在谈论从父实体引用包含的对象,例如:var customerOrderLineItems = customer.Orders [0] .OrderLines; – Justin 2010-07-02 08:40:18

+0

你有几个选择。首先,一些人认为你不应该“伸手”那样的物体。这表明您将对象图视为哑值持有者而不是自包含的自我管理实体。如果一个操作对于一个类来说是不可或缺的,那么它应该是该类的一个操作,根据需要委托给私有对象。如果你需要一个双重派遣的解耦系统,那么访问者模式就是要走的路。任何其他方法都会将多个方法与N * M组关系中的多个对象关联:维护问题。 – 2010-07-02 13:24:28