Specification pattern and CQRS

1,433 views
Skip to first unread message

Daniel Plainview

unread,
Dec 10, 2015, 5:47:39 PM12/10/15
to DDD/CQRS
I'm trying to figure out if Specification pattern has real value today. For me, it looks like Specification pattern has almost no use cases with CQRS approach, since

1. I often query single aggregate root by id or by another unique key like email, login, etc. If I need complex query, it's probably a read side. I don't remember cases with collection of ARs.
2. AR shouldn't contain getters whenever possible.

Do I miss something here?

Vincent van Dijk

unread,
Dec 11, 2015, 1:55:10 AM12/11/15
to DDD/CQRS
Hi Daniel,

"In computer programming, the specification pattern is a particular software design pattern, whereby business rules can be recombined by chaining the business rules together using boolean logic." - https://en.wikipedia.org/wiki/Specification_pattern

Specification pattern can also be used in your domain model.

Vincent.

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Plainview

unread,
Dec 11, 2015, 2:28:07 AM12/11/15
to DDD/CQRS
More specifically, do you use Specification pattern with Repository?

Chris Martin

unread,
Dec 11, 2015, 2:38:49 AM12/11/15
to ddd...@googlegroups.com
The two things have nothing to do with each other. A repository loads your aggregate root (by whatever means). A specification is useful for business rules.

I find them to be a really clean method of ensuring invariants in a system.

say a command comes into your aggregate and you need to check if something exists.

pseudo
`
void Handle(Deposit deposit){
    if(Try(Specifications.AccountExists(accountId).And(Specifications.AccountInGoodStanding(acountId))) 
        RaiseEvent(new DepositAccepted(…)
     else 
         Reject(deposit);
}
`

of course, you can maintain those specifications in other files to keep your aggregates cleaner.

/end ramble.




To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Eve Ragins

unread,
Dec 11, 2015, 4:12:01 AM12/11/15
to DDD/CQRS
Chris, I really like how clean that code looks, but I'm uncertain how specifications come to be. It looks like it's potentially a static method? I guess a better question would be how do specifications get created, assuming "account exists" needs access to external resources?

How are specifications in this sense different from validation?

I guess when I read about specifications in the past I took them to be primarily used to filter down an existing list, such as to find a suitable type of plant for partial shade that has red flowers (and..)

I should note that I don't use any in my application so I'm talking mostly from a theoretical stance.

Greg Young

unread,
Dec 11, 2015, 7:32:30 AM12/11/15
to ddd...@googlegroups.com
this isn't the specification pattern (passing accountId)

these are just static methods
Studying for the Turing test

Daniel Plainview

unread,
Dec 11, 2015, 8:24:47 AM12/11/15
to DDD/CQRS
The two things have nothing to do with each other. A repository loads your aggregate root (by whatever means).

I mean case when you do $fooRepository->findBySpec($spec). IIRC, there was something similar in the Blue book.

Greg Young

unread,
Dec 11, 2015, 8:30:20 AM12/11/15
to ddd...@googlegroups.com
There is. Very few people use the specification pattern at all these days. This is for a few reasons.

1) the weirdness with repositories (is this a specification or a query object?)
2) the existence of line and similar technologies which mostly solve #1

Daniel Plainview

unread,
Dec 11, 2015, 9:21:26 AM12/11/15
to DDD/CQRS
> the existence of line
 
 Do you mean LINQ?

Greg Young

unread,
Dec 11, 2015, 9:22:49 AM12/11/15
to ddd...@googlegroups.com
yes sorry autocorrected.

Chris Martin

unread,
Dec 11, 2015, 3:40:59 PM12/11/15
to ddd...@googlegroups.com
You're right. Those in pseudo code were just static. In my system, the objects behind those static methods are indeed specifications. 

That and this was not real ;)


yes sorry autocorrected.

To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Greg Young

unread,
Dec 11, 2015, 3:43:02 PM12/11/15
to ddd...@googlegroups.com
Yes the spoon never moved.

Kirill Chilingarashvili

unread,
Dec 12, 2015, 1:51:55 AM12/12/15
to DDD/CQRS
I use specification pattern to validate business logic in command methods in my aggregate.
I have set of reusable specs like IsNew, IsNotNew, then next level of reusable specs within domain like ProjectIsSubmitted, AccountRegistrationCompleted etc.
Then I was writing spec per aggregate operation, but then I realized that spec per operation does not make sense if you dont reuse it, so I write business specs inline for that cases.

so the code is like:

Assert<IsNotNew>();
Assert<ProjectIsSubmitted>();


I reuse specs in tests

I found interesting way of reusing same specs in UI.

For example there is a command named "SubmitProject"
I can move command validation into separate spec "CanSubmitProject"
I then can reuse it
- as command guard
- for probing condition in tests
- for probing whether the function is available to interested parties (UI)

I just not feel comfortable with last because to probe it I need to fetch aggregate, so I think the spec should be written to test some interface containing state needed for spec, and then implement it on aggregate/read model

Daniel Plainview

unread,
Dec 12, 2015, 6:18:31 AM12/12/15
to DDD/CQRS
> I use specification pattern to validate business logic
> Assert<ProjectIsSubmitted>()

Are you sure that you need to call it "specification" in that meaning as Evans did? Looks like simple static assertion.

Chris Martin

unread,
Dec 12, 2015, 6:41:15 AM12/12/15
to ddd...@googlegroups.com
Again, that was pseudo code and, admittedly, a bad example.

Yes. My code looks like that. But behind the static assertions are real specifications.

Maybe I should shut my trap around these parts ;)


On Sat, Dec 12, 2015 at 4:18 AM Daniel Plainview <daniel...@gmail.com> wrote:
> I use specification pattern to validate business logic
> Assert<ProjectIsSubmitted>()

Are you sure that you need to call it "specification" in that meaning as Evans did? Looks like simple static assertion.


On Saturday, December 12, 2015 at 9:51:55 AM UTC+3, Kirill Chilingarashvili wrote:
I use specification pattern to validate business logic in command methods in my aggregate.
I have set of reusable specs like IsNew, IsNotNew, then next level of reusable specs within domain like ProjectIsSubmitted, AccountRegistrationCompleted etc.
Then I was writing spec per aggregate operation, but then I realized that spec per operation does not make sense if you dont reuse it, so I write business specs inline for that cases.

so the code is like:

Assert<IsNotNew>();
Assert<ProjectIsSubmitted>();


I reuse specs in tests

I found interesting way of reusing same specs in UI.

For example there is a command named "SubmitProject"
I can move command validation into separate spec "CanSubmitProject"
I then can reuse it
- as command guard
- for probing condition in tests
- for probing whether the function is available to interested parties (UI)

I just not feel comfortable with last because to probe it I need to fetch aggregate, so I think the spec should be written to test some interface containing state needed for spec, and then implement it on aggregate/read model

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Kirill Chilingarashvili

unread,
Dec 12, 2015, 4:34:19 PM12/12/15
to DDD/CQRS
Well it is not static
Assert method looks like this (it's declared on Aggregate base class)
        protected void Assert<TSpec>()
            where TSpec : ISpec, new()
        {
            var spec = new TSpec();
            if (!spec.IsSatisfied(this))
            {
                throw DomainError.Failed(spec);
            }
        }
TItem is the aggregate itself
so spec is just interface 

    public interface ISpec
    {
        bool IsSatisfied(object item);
    }
}

and simple spec looks like:

    public class IsNew : ISpec<Aggregate>
    {
        public bool IsSatisfied(Aggregate item)
        {
            return item.IsNew;
        }
    }

this is spec interface (extended with and, or, not operations) from blue book


so yes, I think it does implement what was meant in blue book

Julian May

unread,
Dec 14, 2015, 2:46:42 AM12/14/15
to DDD/CQRS
We happily use specification pattern in our core domain and the more (business) complex supporting domains. In other, simpler BC's, linq and if/else statements is the way to go.
The composability of businessrules not not only great as a replacement for brittle nested if-statements. We have a lot of different type of customers using the same code-base, so configuration is a big part of our complexity. Factories can compose specifications based on configuration, and those specifications works as the internal logic of validation services etc.
Also, we compose "the other way":
Instead of returning a boolean return value, we return a "SpecificationConclusion" value object which is implicetly intepretable as a boolean, but contains an array of "causes for failure", which compounds as the specification graph is resolved.
This way, we can emit an event describing several reasons why a command did not produce the expected result.

We do not have specifications for AggregateRoots though, and actually do not use get-properties on aggregate-roots for anything besides snapshotting a memento.
The specifications are for specific entities or value objects. This "depth" of modelling only occurs in our more complex BC's, and as such, we only use Specification Pattern in these.

/Julian

Abbey

unread,
Dec 14, 2015, 9:42:36 AM12/14/15
to DDD/CQRS
Agree with Julian. It's simple example.

// Step 1: Define the specification
class ShouldBeAdultSpecification : ISpecification
{
private int _majority;

public ShouldBeAdultSpecification(int majority)
{
_majority = majority;
}

public bool IsSatisfied(Person person)
{
return person.Age >= _majority;
}
}

// Step 2: Register instance of ShouldBeAdultSpecification into IoC container
container.Register<ShouldBeAdultSpecification>(new InjectionConstructor(18));

// Step 3: Apply specification as a business rule to domain object.
// At least 18 years-old to buy wine.
class Person
{
public int Age {get;private set;}

public void BuyWine(int amount)
{
var spec = container.Resolve<ShouldBeAdultSpecification>();

if (spec.IsSatisfied(this))
PutWineIntoCart(amount);
}
}

Daniel Plainview

unread,
Dec 14, 2015, 1:27:12 PM12/14/15
to DDD/CQRS
@Abbey thanks, but your example makes me doubting. In your particular example, I'd probably write something like

class Person
{
   
private int Age

   
public void BuyWine(int amount)
   
{
       
Assertion.greatOrEqual(Age, 18); // or even Assertion.true(Age.isAdult());


       
// ...
   
}
}

If I need some dependencies, I'd probably inject some kind of WinePurchasePolicy.isAllowedToBuy(Age age, ...) along with amount right into BuyWine method.

Specification forces you to have public getter, it may be not that bad, but it's slightly annoying along with service locator in your example.

Greg Young

unread,
Dec 14, 2015, 1:56:17 PM12/14/15
to ddd...@googlegroups.com
On place where the specification can be useful is if you are
dynamically injecting a tree of specifications (e.g. run time
configurable) but this is not usually the main driver.
> --
> You received this message because you are subscribed to the Google Groups
> "DDD/CQRS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to dddcqrs+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



Hendry Luk

unread,
Dec 14, 2015, 8:09:31 PM12/14/15
to ddd...@googlegroups.com
I agree with Greg, this isn't exactly the specification pattern.

The point of specification pattern is to decouple the rules from the execution. E.g. in java:

public class AccountInGoodStandingSpec implements Specification<int> {
@Value("${accounts.healthythreshold}")
BigDecimal accountHealthyThreshold;

@Inject AccountRepository repository;

public boolean isSatisifed(int accountId) {
// etc etc
}
}

public class AccountDepositRules {
@Bean Specification<int> canDepositAccountSpec(AccountExistsSpec accountExistsSpec, AccountInGoodStandingSpec accountInGoodStandingSpec) {
return and(accountExistsSpec, accountInGoodStandingSpec);
}
}

public class DepositHandler {
@Inject Specification<int> canDepositAccountSpec;

public void handle(Deposit deposit) {
if(canDepositAccountSpec.isSatisfied(accountId)){
// etc etc
}
}
}

DepositHandler is decoupled (not just abstracted) from the exact business rules required to determine whether a deposit can be made. These two responsibilities often even belong to different components (or even services).
Suffice to say, this is not a very common pattern for day-to-day if-else situation. Only in complex business rules that require a degree of decoupling and flexibility, commonly used in frameworks such Business Rule Engine or ESB, e.g. Message Router (http://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageRouter.html) in Mule or Camel could be implemented using specification pattern.

Alberto Brandolini

unread,
Dec 15, 2015, 11:58:22 AM12/15/15
to ddd...@googlegroups.com
Hi all, 

one way I use the Specification pattern lately is to be a warning for a draft model, and a blocker for creating an executable model in a similar data structure.

A draft contract could have a MissingSignature as a warning during the negotiation phase/BC, the same specification could be a mandatory check when the contract is signed off or activated.

Splitting the condition from the consequences comes in handy, even though many times the warning happens in the UI.

Cheers

Alberto

Hendry Luk

unread,
Dec 15, 2015, 5:54:07 PM12/15/15
to ddd...@googlegroups.com
And of course, a more mundane example within .net framework itself: the Predicate type used by frameworks such as Linq, Rx, and PLinq.
The idea is to decouple those frameworks from the implementations of filtering rules.
And vice versa, you can write an implementation of Predicate completely agnostic of the underlying execution.

So again, adopting this pattern is mostly relevant only when you're writing a framework like Linq, rx, BRE, or ESB, where you need to externalise rules from the executions. But if you just need to execute a direct if-else, I don't see a point of implementing specification pattern that's only executed directly (i.e. you're not decoupling anything).

Julian May

unread,
Dec 16, 2015, 10:23:23 AM12/16/15
to DDD/CQRS
So again, adopting this pattern is mostly relevant only when you're writing a framework like Linq, rx, BRE, or ESB, where you need to externalise rules from the executions. But if you just need to execute a direct if-else, I don't see a point of implementing specification pattern that's only executed directly (i.e. you're not decoupling anything).

I might not be decoupling the technical aspects of my implementation, but I sure will decouple my domain concepts
Reply all
Reply to author
Forward
0 new messages