Domanda

First off, I'll admit that I'm a newbie to DDD and need to read the "blue book".

I'm building a system that has an AggregateRoot of type "Match". Each Match can have a collection of "Votes" and also has a readonly "VoteCount" property which gets incremented when a user up-votes or down-votes a Match.

Since many users could be voting on a Match at the same time, Votes have to be added/removed from the Match and the VoteCount has to be incremented/decremented as one atomic operation involving write locks (with locks handled by the DB). (I need VoteCount as a static value in the database to be queried on efficiently by other processes/components.)

It seems to me that if I were adhering to strict DDD, I would be coding this operation as such:

An application service would receive a vote request object The service would then retrieve the Match object from a Match Repository The service would then call some sort of method on the Match object to add the Vote to the collection and update VoteCount. The Repository would then persist that Match instance back to the DB However, this approach is not feasible for my application for 2 main reasons, as I see:

I'm using MongoDB on the backend and cannot wrap this read-write operation into a transaction to prevent dirty reads of the Match data and its associated Votes and VoteCount.

It's highly inefficient. I'm pulling back the entire object graph just to add a Vote and increment VoteCount. Although this is more efficient in a document db than in a relational one, I'm still doing an unnecessary read operation.

Issues 1 & 2 are not a problem when sending a single Vote object to the repository and performing one atomic update statement against Mongo.

Could Vote, in this case be considered an "aggregate" and be deserving of its own repository and aggregate status?

È stato utile?

Soluzione

Could Vote, in this case be considered an "aggregate" and be deserving of its own repository and aggregate status?

I think this might be the right answer. An aggregate should be a transactional consistency boundary. Is there a consistency requirement between votes on a match? The presents of a Vote collection on a Match aggregate would suggest that there is. However, it seems like one vote has nothing to do with the next.

Instead, I would store each vote individually. This way you can use the aggregate functionality of MongoDB to get the count, though I'm not sure whether it is still slow. If it is, then you can aggregate using the Map/Reduce functionality.

More generally, this may not be a best fit for DDD. If the domain doesn't consist of complex behavior there is hardly a reason to try to adapt the DDD tactical patterns (entity, agreggate) to this domain.

Altri suggerimenti

Yes, you can model Vote as an aggregate unto itself. In the real world, often people vote for several things at once. The aggregate would then be called a Ballot instead of vote. You just have a special case where there is only one item to vote for at a time.

I can't speak for MongoDB (perhaps someone else can) - but you would have a very easy time doing this in RavenDB with something like:

public class Match
{
    public string Id { get; set; }
    public string Name { get; set; } // or whatever
}

public class Vote
{
    public string Id { get; set; }
    public string MatchId { get; set; }
    public string UserId { get; set; }
    public bool YeaOrNay { get; set; } // or whatever
}

Then you would just build a map/reduce index over your votes to tally the results.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top