Reputation: 4103
I have been struggling to understand DDD. Here is a scenario that boggles me. Say we have the entity Fund which has value object allocation/holdings and historical prices. What if a service only wants allocations of a particular fund? Should we return a list of allocation objects or return a Fund entity that contains a list of allocations? If we resort to the first approach, we need to create an Allocation Repository. The second approach seems a bit weird, since the entity is being modified to return only certain value objects to the service. Without much knowledge about the entity, shouldn't the service have all fund fields accessible to it?
My description might not be accurate. Please let me know if I need to clarify my post.
class Fund
{
int fundId;
List<Allocation> allocations;
List<Holding> holdings;
}
class Allocation
{
string type;
string percentage;
}
Upvotes: 7
Views: 5178
Reputation: 13246
I may not quite understand your domain so let me know if I get this wrong. When we take the Order
/ OrderLine
scenario we may model OrderLine
as a VO (much like your Fund
/ Allocation
). Why would we ever want to query a service to return just a list of the OrderLine
objects for an Order
? :)
However, if you really need to do this you should be loading the Fund
instance and using its contained Allocations
list. However, querying your domain model usually leads to problems (lazy-loading, fetching strategies, and moving away from tell-don't-ask). If you do need to query, consider creating a lightweight query model (some call it a read model) that performs this function.
Typically you wouldn't have a repository of VOs. If you have a fixed list of VOs then you could use a type of enum
structure. In C# you could do this with readonly
class instances. Vaughn Vernon calls this 'Standard Types' (if memory serves). I don't think you have that scenario, though.
Upvotes: 2
Reputation: 2929
There is multiple variations of repository implementations but I would not mind returning a list of Allocation IF, and ONLY IF, Allocation is never managed on it's own.
In other words, if you will, at some point, want to get information about an Allocation, no matter which Fund it belongs to, then you will need a repository for Allocations, and if you are making such a repository, then you should have a method like getAllocationsbyFundId(int id)
or somethign similar. If it doesn't make sense to look at Allocations on their own without knowning which Fund it is from, then Allocations are really a part of Fund and it would make complete sense to have a method on your Fund repository to return the Allocations of a specific Fund.
If you, however, end up with a GetAllAllocation()
method on your Fund repository, then you have slipped out of a clean pattern.
Upvotes: 8
Reputation: 5128
To answer the question in the title, no you should not. The repository pattern only works if the items in the repository have identity. If an object has identity then it is an entity not a value object.
Value objects should be all or nothing, e.g. changing one property on a value object replaces the entire thing. Thus a value object is immutable after creation.
That is not to say that a version of a value object internal to the repository cannot have an identity, but you should not let persistence concerns alter your domain.
Based on your description it actually sounds like Allocation
is an entity, because it is differentiable and thus has identity.
Assuming that Allocation
is an entity, the question I would then be asking is should Allocation
be its own aggregate.
Upvotes: 11