我一直在努力了解DDD。这是一个困扰我的场景。假设我们拥有实体基金,其具有价值对象分配/持有和历史价格。如果服务只想要特定基金的分配怎么办?我们应该返回分配对象列表还是返回包含分配列表的基金实体?如果我们采用第一种方法,我们需要创建一个分配存储库。第二种方法似乎有点奇怪,因为正在修改实体以仅将某些值对象返回给服务。如果对该实体缺乏了解,该服务是否应该可以访问所有基金领域?
我的描述可能不准确。如果我需要澄清我的帖子,请告诉我。
class Fund
{
int fundId;
List<Allocation> allocations;
List<Holding> holdings;
}
class Allocation
{
string type;
string percentage;
}
答案 0 :(得分:8)
要回答标题中的问题,不,不应该。仅当存储库中的项具有标识时,存储库模式才有效。如果一个对象具有标识,那么它就是一个实体而不是一个值对象。
值对象应该是全部或全部,例如更改值对象上的一个属性会替换整个事物。因此,值对象在创建后是不可变的。
这并不是说存储库内部的值对象的版本不能具有标识,但是您不应该让持久性问题改变您的域。
根据您的描述,实际上听起来Allocation
是一个实体,因为它是可区分的,因此具有同一性。
假设Allocation
是一个实体,那么我要问的问题是Allocation
应该是它自己的聚合。
答案 1 :(得分:4)
存储库实现有多种变体,但我不介意返回分配IF的列表,只是如果,分配永远不会自行管理。
换句话说,如果您希望获得有关分配的信息,无论它属于哪个基金,那么您将需要一个分配存储库,如果您正在建立这样的存储库,那么你应该有getAllocationsbyFundId(int id)
或类似的方法。如果在没有知道它来自哪个基金的情况下单独查看分配是没有意义的,那么分配实际上是基金的一部分,并且在您的基金存储库中有一个方法来返回分配的完全有意义。特定基金。
但是,如果您在您的基金存储库中以GetAllAllocation()
方法结束,那么您已经摆脱了干净的模式。
答案 2 :(得分:1)
我可能不太了解你的域名,所以如果我弄错了,请告诉我。当我们采用Order
/ OrderLine
方案时,我们可能会将OrderLine
建模为VO(非常类似于您的Fund
/ Allocation
)。为什么我们要查询服务只返回OrderLine
的{{1}}个对象列表? :)
但是,如果确实需要执行此操作,则应加载Order
实例并使用其包含的Fund
列表。但是,查询域模型通常会导致出现问题(延迟加载,获取策略以及远离tell-not-ask)。如果确实需要查询,请考虑创建一个执行此功能的轻量级查询模型(有些称之为读取模型)。
所以我同意Mgetz你应该有一个VOs存储库。如果您有一个固定的VO列表,那么您可以使用一种Allocations
结构。在C#中,您可以使用enum
类实例执行此操作。 Vaughn Vernon将此称为“标准类型”(如果内存服务)。不过,我不认为你有那个场景。