Generally saying Specification is a predicate that determines if an object does or does not satisfy some criteria. By using Specifications you could easily recombine business logic together using boolean logic.
Have you ever thought that bool TryParse(string s, out int result) could be seen as some pattern? Yes we could talk about this method like about specification of integer represented in string, and this is validation usage. This pattern also could be used not only for Validation, but also for Queuring and Building purposes.
Let us imagine that we need to validate if some Patient is eligible for drugs procedures at home provided by nurse.
So this we will need two specifications. If they are both satisfied we could say that this patient is eligible for drugs procedures at home. First specification
You could say that we can put all verification in our method FetchPatientsForVisitWithDrugs. Yes, but this is not right way, because your specifications could be used in different locations and also if see this from DDD perspective you always need to bring concept things into the light.
Another question: Don’t you see this systax if(drugsSpec.IsSatisfiedBy(patient) && nurseVisit.IsSatisfiedBy(patient)) to be boring systax? Yes, especially if you have many specifications.
Let us improve our design.
First we will add some methods to our interface like here:
publicinterfaceISpecification
{
bool IsSatisfiedBy(Patient patient);
ISpecification And(ISpecification secondSpec);
ISpecification Or(ISpecification secondSpec);
ISpecification Not(ISpecification secondSpec);
}
And also will add CompositeSpecification which will be abstract base class for our two existing.
Classes returned by different method of this new CompositeSpecification are used to combine few specifications in order to build new complicated one. They could look simple like this AndSpecification class:
Now we work with this new specification as with simple single one: if(specification.IsSatisfiedBy(patient)) With other specifications like OrSpecification and NotSpecification we could build more complicated queries.
For example I will show some possible usage of this in Nhibernate:
Specification declares requirements to the output but do not expose how those results are reached.
Rules are defined explicitely. This means that developer could know what to expect from the specification even without knowledge how that is realized.
You get flexible interface, which could be easily enhanced. You also could build your composite specifications for queuring.
Another good advantage is possitility to test everything easily. You just define fail, non-fail states of the object and verify by checking boolean result.
Just now I'm working with some specifications and remind your article. There are cases, when we want to know first specification which fails (for example to correct it).
I'm using following pseudocode:
Specification sp1, sp2, sp3, … …….. If Not sp1.IsSatisfiedBy(a_data) Then Return sp1.Message ElseIf Not sp2.IsSatisfiedBy(a_data) Then Return sp2.Message ElseIf Not sp3.IsSatisfiedBy(a_data) Then Return sp3.Message ………. EndIf
I'll think how to improve this code for usage in CompositeSpecification :)
The simplest way I see is to throw exceptions on each verification, but this is not really good approach.
Second about I think is to add some property/method to specification like GetErrorMessage() or GetExactFailedSpecificating which could pass through all composite classes.
This website uses cookies. We'll assume you're ok with this, but you can opt-out if you wish.AcceptRead More
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
nice post! I always liked idea of chaining, but, unfortunately, I always forget about it while writing some peace of software :)
Just now I'm working with some specifications and remind your article.
There are cases, when we want to know first specification which fails (for example to correct it).
I'm using following pseudocode:
Specification sp1, sp2, sp3, …
……..
If Not sp1.IsSatisfiedBy(a_data) Then Return sp1.Message
ElseIf Not sp2.IsSatisfiedBy(a_data) Then Return sp2.Message
ElseIf Not sp3.IsSatisfiedBy(a_data) Then Return sp3.Message
……….
EndIf
I'll think how to improve this code for usage in CompositeSpecification :)
The simplest way I see is to throw exceptions on each verification, but this is not really good approach.
Second about I think is to add some property/method to specification like GetErrorMessage() or GetExactFailedSpecificating which could pass through all composite classes.