views:

744

answers:

6

Having Watched this video by Greg Yound on DDD

http://www.infoq.com/interviews/greg-young-ddd

I was wondering how you could implement Command-Query Separation (CQS) with DDD when you have in memory changes?

With CQS you have two repositories, one for commands, one for queries. As well as two object groups, command objects and query objects. Command objects only have methods, and no properties that could expose the shape of the objects, and aren't to be used to display data on the screen. Query objects on the other hand are used to display data to the screen.

In the video the commands always go to the database, and so you can use the query repository to fetch the updated data and redisplay on the screen.

Could you use CQS with something like and edit screen in ASP.NET, where changes are made in memory and the screen needs to be updated several times with the changes before the changes are persisted to the database?

For example

  1. I fetch a query object from the query repository and display it on the screen
  2. I click edit
  3. I refetch a query object from the query object repository and display it on the form in edit mode
  4. I change a value on the form, which autoposts back and fetches the command object and issues the relevant command
  5. WHAT TO DO: I now need to display the updated object as the command made changes to the calculated fields. As the command object has not been saved to the database I can't use the query repository. And with CQS I'm not meant to expose the shape of the command object to display on the screen. How would you get a query object back with the updated changes to display on the screen.

A couple of possible solutions I can think of is to have a session repository, or a way of getting a query object from the command object. Or does CQS not apply to this type of scenario?

It seems to me that in the video changes get persisted straight away to the database, and I haven't found an example of DDD with CQS that addresses the issue of batching changes to a domain object and updating the view of the modified domain object before finally issuing a command to save the domain object.

A: 

In memory, you would usually use the Observer design pattern.

Actually, you always want to use this pattern but most databases don't offer an efficient way to call a method in your app when something in the DB changes.

Aaron Digulla
Not sure if you get my question.With CQS you are separating the reads from the writes. Where the Query repository is separate from the Write repository.So if I don't save the domain entity to the repository, how can the query repository fetch the data?Would I need a way to get a query object from the domain object with it updated state, or are you saying a query object would observe a domain object and update itself?Or possibly introduce a session repository?
A: 

The Unit of Work design pattern from Patterns of Enterprise Application Architecture matches CQS very well - it is basically a big Command that persist stuff in the database.

Mark Seemann
Thanks for the link, but still doesn't answer my question.Basically with CQS you have one object which just has methods (the commands), and another object which contains the shape of the object.There are two repositories, one for the command object, and one for the query object.So you never use the command object to repopulate the screen, instead you use the query object.Without saving the changes of the command object to the database, how do you redisplay the changes made by calling the commands?Since the changes are not in the database, you can't use the query repository.
+1  A: 

If you really want to use CQS for this, I would say that both the Query repo and the Write repo both have a reference to the same backing store. Usually this reference is via an external database - but in your case it could be a List<T> or similar.

Erik Forbes
Thanks for the reply.I'm wondering how common/good a design it is to use CQS when the changes are in memory, rather than persisted straight to the database?This is basically what we have come up with is to use session repositories to allow the query repository to access the command data via a session variable.Maybe need HttpContext repositories later.Has anyone seen this implemented before? Thoughts appreciated.
In my opinion, the method you use to manipulate a data source shouldn't rely on the kind of data source. The Repository pattern allows you to abstract these differences away, allowing you to treat any data source as if it were a queryable collection of objects. It's up to the individual repository implementations to determine the target data source - so in theory you'd have a 'InMemoryRepository' and a 'DatabaseRepository' - or what have you.
Erik Forbes
Yeah I understand that you can swap the InMemory repository for the Database repository. Part of the value of CQS is that you issue commands to the database, and separately pull back the updated data with the query repository. In memory the command object is in session, so the query repository can only pull back data in the command object. With the database version then the query object can be totally different to the command object, just seems with the memory CQS the relationship is a lot closer. Wondering how this fits in with what CQS was trying to achieve
There's no rule saying that your query repository and your command repository can't share a common backing store. That's what you're doing when you use the database. Sharing a List<T> is pretty much the same as sharing a database connection, as far as this abstraction goes.
Erik Forbes
+2  A: 

So what it sounds like you want here is a more granular command.

EG: the user interacts with the web page (let's say doing a check out with a shopping cart).

The multiple pages getting information are building up a command. The command does not get sent until the user actually checks out where all the information is sent up in a single command to the domain let's call it a "CheckOut" command.

Presentation models are quite helpful at abstracting this type of interaction.

Hope this helps.

Greg

Hi Greg,do you have an examples of this?At the moment I have gone down the route of taking the query object, and putting it in a "shopping cart" object, which serializes the query object to allow changes between postbacks (could use session also). Once the object has finished being updated it is passed to the command object.If I had more time then could use a different object than the query object for storing these in edit changes, like a presentation model.I'm using the same object to display and edit with, is this the same with your proposed presentation model?Thanks
+1  A: 

Also for the rest of your concerns ...

These are more so concerns with eventual consistency as opposed to CQRS. You do not need to be eventually consistent with CQRS you can make the processing of the command also write to the reporting store (or use the same physical store for both as mentioned) in a consistent fashion. I actually recommend people to do this as their base architecture and to later come throught and introduce eventual consistency where needed as there are costs azssociated with it.

Not sure if this applies to my situation yet, so far only have the one database, so don't have to worry about updating the reporting store, and the command objects use NHibernate so changes are persisted back to the database.Or does this apply to my situation? Not sure which concern you where referring to?
A: 

JdonFramework is CQRS DDD java framework, it supply a domain events + Asynchronous pattern, more details https://jdon.dev.java.net/

banq