Using Specification pattern with CQRS+Event Store

533 views
Skip to first unread message

Bogdan Prishedko

unread,
Sep 20, 2010, 8:32:54 AM9/20/10
to DDD/CQRS
Hi.
I’m doing investigation of using CQRS+DDD+Event Store for one project.
And I couldn’t find answer on the following question: how
Specification pattern can be used in such configuration? There is
example of using Specification with Repository in book “Domain-Driven
Design: Tackling Complexity in the Heart of Software”, but such
approach is OK only if we use RDBMS for domain, and it doesn’t work if
we use Event Store, because of we can only get AR from Repository by
ID.
This question looks like issue of uniqueness that is discussed on
http://groups.google.com/group/dddcqrs/browse_thread/thread/745e86b5078c32e7
and http://groups.google.com/group/dddcqrs/browse_thread/thread/69496d381d9afb76,
but IMHO issue with Specification is more common. So I see the
following ways of solutions for it:
1. Repository can ask reporting tables for getting list of IDs of ARs
that can satisfy given specification. I don’t like this way because of
coupling command part with query part. Service(s) can be used for
isolation such coupling (for example SpecificationService with method
Collection<UUID> findSatisfied(Specification spec), but I feel that it
is something wrong with it.
2. Repository loads all ARs of given type and pass them to given
specification. I know that it is awful from performance point of view.
3. Find IDs of required ARs on client side and pass them with command
in domain.
What from suggested solutions is good enough from your point of view?
Are there other solutions for this issue? Or maybe I’m trying to solve
it in wrong way?

Thanks.

Greg Young

unread,
Sep 20, 2010, 11:08:20 AM9/20/10
to ddd...@googlegroups.com
Why do you need to use it? Can you give an example?

--
Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer
de votre attention

seagile

unread,
Sep 20, 2010, 11:16:08 AM9/20/10
to DDD/CQRS
1. There's nothing wrong with making querying a two step process
(query for primary keys first using secondary attributes, and then
query for aggregates): that's how a database works. How you implement
this depends on the desired consistency.
2. Is something that reminds me of that very "blond" female developer
I worked with one time: she always fetched the entire database to do a
single action/command. Don't do that.
3. Is a good option when you're not all that worried about
consistency.

On 20 sep, 14:32, Bogdan Prishedko <prishe...@gmail.com> wrote:
> Hi.
> I’m doing investigation of using CQRS+DDD+Event Store for one project.
> And I couldn’t find answer on the following question: how
> Specification pattern can be used in such configuration? There is
> example of using Specification with Repository in book “Domain-Driven
> Design: Tackling Complexity in the Heart of Software”, but such
> approach is OK only if we use RDBMS for domain, and it doesn’t work if
> we use Event Store, because of we can only get AR from Repository by
> ID.
> This question looks like issue of uniqueness that is discussed onhttp://groups.google.com/group/dddcqrs/browse_thread/thread/745e86b50...
> andhttp://groups.google.com/group/dddcqrs/browse_thread/thread/69496d381...,

Bogdan Prishedko

unread,
Sep 21, 2010, 2:21:58 AM9/21/10
to DDD/CQRS
Hi Greg.

There is one of cases where Specification can be used (it's
translation from use case of medical card creation):
"Patient with such full name and date of birth exists: System shows
warning: "Patient [full name] [date of birth] exists. Create new
patient with the same data?". If user clicks "Create", system
continues medical card processing. If user clicks "Cancel", system
shows first dialog of new patient registration".

Rickard Öberg

unread,
Sep 21, 2010, 2:35:54 AM9/21/10
to ddd...@googlegroups.com

Why can this not be achieved by doing a simple data query, instead of
using Specification pattern against repository?

/Rickard

Bogdan Prishedko

unread,
Sep 21, 2010, 2:38:03 AM9/21/10
to DDD/CQRS
Hi Seagile.

Thank you for your answer. And it is good point about "blond
developer" :-) I'm not going to use solution 2, but I've written it
only for preventing suggestions like this: "If you have small amount
of data, it'll be OK to load all ARs and iterate over them".

Bogdan Prishedko

unread,
Sep 21, 2010, 2:41:50 AM9/21/10
to DDD/CQRS
Hi Rickard.

Could you please specify what "simple data query" means? Query object?
Or just SQL query to reporting DB like "select count(*) from patient
where ..."?

Rickard Öberg

unread,
Sep 21, 2010, 2:45:21 AM9/21/10
to ddd...@googlegroups.com

The latter.

/Rickard

Bogdan Prishedko

unread,
Sep 21, 2010, 2:54:10 AM9/21/10
to DDD/CQRS
I'd like to use Specification because of it will make less coupling
between command and reporting parts than sending specific queries for
each case, and Specification encapsulates part of business rule and
allows to combine business rules in simple way.

Nuno Lopes

unread,
Sep 21, 2010, 3:56:55 AM9/21/10
to ddd...@googlegroups.com
Why have that in the Command handlers? It looks to me that what you describe is more user interaction rule rather a Core business rule.

Sent from my iPhone

Bogdan Prishedko

unread,
Sep 21, 2010, 4:21:46 AM9/21/10
to DDD/CQRS
Hi Nuno.

You are right, it looks like user interaction, but it is quotation
from use case, so it is why it looks in this way. Business rule is:
"Patients must be identificated by passport number. But if patient
comes without passport, his full name and date of birth must be
checked for preventing patients duplication. If system contains
patient with given full name and date of birth, user must be warned
and, if user decides to create new patient with existed full name and
date of birth, this patient must be marked as required of
clarification of identification information."
So checking of user data looks like part of business rule, and I want
to have that checking on command side, because I don't like having
business logic on client side and because of such solution provides
more strong consistency than if this logic is on client side.

Greg Young

unread,
Sep 21, 2010, 4:21:50 AM9/21/10
to ddd...@googlegroups.com
This is roughly equivalent to the unique cosntraint problem that comes
up periodically here.

If you look in the archives there is much discussion. Also I put up
one of my responses to it here
http://codebetter.com/blogs/gregyoung/archive/2010/08/12/eventual-consistency-and-set-validation.aspx

--

Bogdan Prishedko

unread,
Sep 21, 2010, 5:26:13 AM9/21/10
to DDD/CQRS
Greg, your suggestion is very good for adding additional asynchronous
checking, that provides stronger consistency: if event handler detects
patient duplication (RDMS unique constraints can be use for this), we
marked duplicated patients as required patient info clarification or
patients merging.

In my case detection of duplication must be synchronous, and it can be
even with more relaxed consistency than in your solution. So it should
be placed in client or in command side.

But I have one disturbing thought about your solution: it looks like
moving domain logic from domain, doesn't it? My case and case with
user registration are very simple. But more complicated checks exist,
and you suggest common approach with moving all such checks in event
handlers. So in this case logic that usually encapsulated in
Specifications or Services (if more than one AR are used in business
rule) will be spread all over domain and reporting.


On Sep 21, 11:21 am, Greg Young <gregoryyou...@gmail.com> wrote:
> This is roughly equivalent to the unique cosntraint problem that comes
> up periodically here.
>
> If you look in the archives there is much discussion. Also I put up
> one of my responses to it herehttp://codebetter.com/blogs/gregyoung/archive/2010/08/12/eventual-con...

Nuno Lopes

unread,
Sep 21, 2010, 8:52:19 AM9/21/10
to ddd...@googlegroups.com
Hi Bogdan,

There are two steps in this activity:

"But if patient
comes without passport, his full name and date of birth must be
checked for preventing patients duplication. If system contains
patient with given full name and date of birth, user must be warned
and,"

This step is an UI issues. Basically the UI gives the opportunity to the user to proceed or not. Imagine an AJAX call while the user types the name and birth.

"if user decides to create new patient with existed full name and
date of birth, this patient must be marked as required of
clarification of identification information."

Fine. This clarification is a consequence driven by the fact that the user has not presented the Passport and there is other similar data or any other Personal Identification.

The question I ask is - if the name and date of birth is totally different would the clarification activity start?

If so all we need to have two command

RegisterPatient(....) // requiring some sort of personal identification;
RegisterPatientForFurtherVerification(....) // not requiring the passport ID.

Later someone will verify the data and submit the info with:

VerifyPatient(....) ...

Doe this help?

Nuno

Nuno Lopes

unread,
Sep 21, 2010, 8:56:37 AM9/21/10
to ddd...@googlegroups.com
By the way. Verification could be automatic. Say a process that looks up for unverified patient registrations, and find if there are similar patients. If there aren't similar patients, it automatically sends the command VerifyCustomer ... if found some it could send an email or some other kind of alert.

Nuno

Bogdan Prishedko

unread,
Sep 21, 2010, 9:22:24 AM9/21/10
to DDD/CQRS
Nuno, thank you for your suggestions. They are really helpful. And
they have shown me that I have granularity issue in my analysis: it
looks like my commands have more responsibility that they should.

On Sep 21, 3:56 pm, Nuno Lopes <nbplo...@gmail.com> wrote:
> By the way. Verification could be automatic. Say a process that looks up for
> unverified patient registrations, and find if there are similar patients. If
> there aren't similar patients, it automatically sends the command
> VerifyCustomer ... if found some it could send an email or some other kind
> of alert.
>
> Nuno
>
Reply all
Reply to author
Forward
0 new messages