Monthly Archives: June 2010
Note: This post originated from an email discussion I had with a colleague. I’ve removed/replaced the specifics of our core domain (hopefully this hasn’t diluted the points I’m trying to make too much!)
While I consider that a focus on capturing intent to be an exciting part of CQRS from a core software design perspective, I believe it is achieving the distillation part of DDD, separating our core domain from supporting domains, that allows us to maximise our potential ROI from the application of CQRS (with event sourcing).
From a business stance, we have chosen as a company to focus on a core domain to differentiate us from our competitors. Our management/marketing team have decided that this area of business provides our advantage over competitor products. From that perspective, it makes sense that we channel our efforts into ensuring that our software model is optimised for this purpose. As a result, we need to spend less effort working on our supporting domains and more effort on our core domain.
I would therefore argue that we should not apply the same level of analysis and design on our supporting domains, as we do on our core model – these areas provide little ROI by comparison.
Whilst I agree that moving away from the CRUD mentality is vital in our core domain, it is not so essential in supporting domains. The level of complexity in our supporting domains is insufficient to justify the costs of applying complex modelling techniques to these areas. Supporting domains could potentially be created using RAD tools, bought off the shelf where possible, or even outsourced. In any of these cases, it is the distillation process that allows us to identify a clean separation between sub-domains – a separation we need to maintain in our code base.
A really interesting article on this can be found here, the concepts from which originate in Eric Evans DDD book.
It’s taken quite a while, but I think I’ve had a bit of a revelation in really grokking the application of CQRS, Event Sourcing and DDD.
I’ve been considering the application of CQRS to a multi-user collaborative application (actually suite of applications) at the company I work. For some parts of the application, it is really easy to visualise how the application of CQRS would provide great benefits, but for others, I couldn’t quite figure out how the mechanics of such a system could be put into place, and yet maintain a decent user experience.
Let me try to elaborate with a couple of examples:
In one application I work on, a user may make a request for a reservation. I can see this working well under CQRS. The command can be issued expecting to succeed, and the response needn’t be instant; a message informing the user that their request is being processed, and that they will be notified of the outcome should suffice. The application can then take responsibility of checking the request against its business rules, and raising relevant events accordingly (reservation accepted, reservation denied etc). Supporting services could also notify users of the system when other events they might be interested in, become available.
For another scenario in the same application, a user may wish to update their address details. The application must store this information, however the application does not use this information in any way shape or form. It is there for other users to reference. When applying CQRS to this area, we start to see some oddities. A user receiving a notification that their request to update address is being processed seems ridiculous; there is no processing required here. In addition to this, this canonical example of “capturing intent” doesn’t really apply to our domain; in our domain no one cares why the user is updating their address, be it because of a typo, or because of a change of address. This information isn’t interesting in to any of the users of the system.
Then it hit me.
CRUD actions like modifying the contact address of an employee and other ancillary tasks – provide only supporting value in our domain. For all intents and purposes, the contact address of an employee is just reference data; it is there to support our actual domain. Arguably then, there is no benefit for modelling this interaction within our domain model. It’s quite the contrary in fact; diluting our core domain model with uninteresting concerns blurs the focus from what’s important. Paraphrasing Eric Evans’ blue book: anything extraneous makes the Core Domain harder to discern and understand.
Taking this idea further, there can be significant benefit in separating this kind of functionality from actions that belong to our core domain. In code terms, this means that our domain model will not have an “Employee” entity with a collection of type “ContactAddress”. This association isn’t interesting in our core domain. It is likely that it is part of supporting model which could be implemented quickly and effectively using any one of Microsoft’s (or any other manufacturer’s) RAD tools.
In the big blue DDD book, I think Evans describes this separation as a generic sub-domain. In generic/supporting sub-domains there may be little or no business value in applying complex modelling techniques even though the function they provide is necessary to support our core domain. Alternatively, the core-domain of one application may become a supporting domain of another. In either case, the models should be developed, and packaged separately.
Our product, in its various forms, contains enough complexity in its problem domain itself, without complicating things further by tangling up the core domain with supporting concerns. I do not wish to be in the situation (again) where one application needs to know the ins and outs of what is supposed to be another discrete application. If understanding the strengths and limitations of modelling techniques such as CQRS, Event Sourcing and DDD can help me achieve this, then I’m making small steps in the right direction!
NB: this post originated from an email discussion I had with a colleague. I’ve removed/replaced the specifics of our core domain (hopefully this hasn’t diluted the points I’m trying to make too much!)
The next cool thing I found on the same site can be seen here:
Basically, the author identifies a “code-smell” and applies a pattern to aid maintainability. The cool thing here is the link to “view, run, & edit code” for each example:
…which integrates with an site, http://jsfiddle.net, allowing the sample to be modified and run within the browser:
Very cool stuff indeed.
Found this article today, and after subsequently checking out a few of the authors other posts (in particular, his excellent series on CQRS), I proceeded to add his blog to my Google Reader.