Discussion:
Specification Pattern vs Query Objects
michal_talaga
2007-02-07 08:32:55 UTC
Permalink
Hello!

For some time I have been thinking on the following two sentence:
"Yet another approach for querying is to use the Specification
pattern" ... "Even those Specification classes could very well spit
out IQuery"

Those are sentences from Jimmy Nilsson's book on DDD.

As much as I like the specification pattern and the possibility to
use it with repositories like this:

Rository r = new Repository();
Specification s = new LongNameSpecification();
User[] users = r.GetBySpec(s);

I have simply no idea, what should I do with the specification object
when it comes to real implementation when using some kind of data
mapper or a plain sql even.
Jimmy Nilsson states that Specification can spit IQuery (some kind of
Query Object). OK. If I had IQuery i can work with it, but how do I
get it? I cannot accept coding the same logic once in the
IsSatisfiedBy method and once to spit IQuery and I have no idea how
to do it otherwise.
Any suggestions?
--
Michal





Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/domaindrivendesign/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/domaindrivendesign/join
(Yahoo! ID required)

<*> To change settings via email:
mailto:domaindrivendesign-***@yahoogroups.com
mailto:domaindrivendesign-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
domaindrivendesign-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
michal_talaga
2007-03-05 08:44:08 UTC
Permalink
Oh well. Based on the input it seams that noone knows the answer for
this question. I just wonder how you guys use the specification
pattern if it cannot be easily translated to some persistance
specific constructs.
--
Michal
Post by michal_talaga
Hello!
"Yet another approach for querying is to use the Specification
pattern" ... "Even those Specification classes could very well spit
out IQuery"
Those are sentences from Jimmy Nilsson's book on DDD.
As much as I like the specification pattern and the possibility to
Rository r = new Repository();
Specification s = new LongNameSpecification();
User[] users = r.GetBySpec(s);
I have simply no idea, what should I do with the specification
object
Post by michal_talaga
when it comes to real implementation when using some kind of data
mapper or a plain sql even.
Jimmy Nilsson states that Specification can spit IQuery (some kind of
Query Object). OK. If I had IQuery i can work with it, but how do I
get it? I cannot accept coding the same logic once in the
IsSatisfiedBy method and once to spit IQuery and I have no idea how
to do it otherwise.
Any suggestions?
--
Michal
------------------------ Yahoo! Groups Sponsor --------------------~-->
Check out the new improvements in Yahoo! Groups email.
http://us.click.yahoo.com/4It09A/fOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
berthooyman
2007-03-05 10:01:49 UTC
Permalink
Is a query object a specification? Is a textual query representation in
some object query language a specification? Those two approaches strike
me as the most obvious options to this.

Transforming either of them into an SQL construct is a traditional
Object-relational mapping problem (I suppose when a problem is qualified
as traditional this implies that it's already solved).

Repository r = new Repository();
Specification s = new Criteria("lastname like 'Tala%' and city='New
York' ")
User[] newYorkTalaSomethingUsers = r.match(s);
Post by michal_talaga
Oh well. Based on the input it seams that noone knows the answer for
this question. I just wonder how you guys use the specification
pattern if it cannot be easily translated to some persistance
specific constructs.
--
Michal
Post by michal_talaga
Hello!
"Yet another approach for querying is to use the Specification
pattern" ... "Even those Specification classes could very well spit
out IQuery"
Those are sentences from Jimmy Nilsson's book on DDD.
As much as I like the specification pattern and the possibility to
Rository r = new Repository();
Specification s = new LongNameSpecification();
User[] users = r.GetBySpec(s);
I have simply no idea, what should I do with the specification
object
Post by michal_talaga
when it comes to real implementation when using some kind of data
mapper or a plain sql even.
Jimmy Nilsson states that Specification can spit IQuery (some kind
of
Post by michal_talaga
Query Object). OK. If I had IQuery i can work with it, but how do I
get it? I cannot accept coding the same logic once in the
IsSatisfiedBy method and once to spit IQuery and I have no idea how
to do it otherwise.
Any suggestions?
--
Michal
michal_talaga
2007-03-06 23:10:24 UTC
Permalink
Post by berthooyman
Is a query object a specification?
no
Query Object:
http://www.martinfowler.com/eaaCatalog/queryObject.html

Specification:
http://www.martinfowler.com/apsupp/spec.pdf

I know how to deal with Query Objects. I don't know how to deal with
Specifications.
jupitermoon_beam
2007-03-07 16:31:14 UTC
Permalink
I agree.

A query object is an interpreter (Gang of Four). Its purpose is to
abstract a database or search query.

A specification is used to abstract a boolean satisfaction. For
example Specification.IsAGoodPayingCustomer(Customer). The
specification contains business logic which determines wether the
object meets it.

Another example of a specification is validation.

Of course you can use specification to find matching objects for
example in a collection (e.g. the predicate delegate in .NET).

This is where specification vs query becomes complex as a repository
is supposed to act like a collection and therefore it makes sence to
use a specification on a repository. Therefore a query could be
written as a specification but implement the interpreter pattern
within the repository (as Tim McCarthy's post suggests). This keeps
the DB logic out of the domain.
Post by michal_talaga
Post by berthooyman
Is a query object a specification?
no
http://www.martinfowler.com/eaaCatalog/queryObject.html
http://www.martinfowler.com/apsupp/spec.pdf
I know how to deal with Query Objects. I don't know how to deal with
Specifications.
------------------------ Yahoo! Groups Sponsor --------------------~-->
Check out the new improvements in Yahoo! Groups email.
http://us.click.yahoo.com/4It09A/fOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
michal_talaga
2007-03-08 08:42:11 UTC
Permalink
Post by jupitermoon_beam
This is where specification vs query becomes complex as a repository
is supposed to act like a collection and therefore it makes sence to
use a specification on a repository. Therefore a query could be
written as a specification but implement the interpreter pattern
within the repository (as Tim McCarthy's post suggests). This keeps
the DB logic out of the domain.
Tim's solution only deals with most simple cases i.e.: field quals
value.
You can extend it a bit to work with ranges for example. But! This will
not be a generic solution and it will not handle complex specifications
with method calls, checks for values of nested objects etc. If you want
to use such a complex specification, I see no other way than to
duplicate at least some part of the logic.
Still I see now way to use specifications in a real world senario prior
to C# 3.0.
--
Michal
michal_talaga
2007-03-08 08:43:32 UTC
Permalink
By saying "I see no way" I meant the Data Mapper scenario ;-)
--
Michal
jupitermoon_beam
2007-03-08 09:32:43 UTC
Permalink
Post by michal_talaga
Post by michal_talaga
By saying "I see no way" I meant the Data Mapper scenario ;-)
I agree it is difficult hence the existance of the Query object.

Eric does mention is his book that even though the purpose of the 4
layer architecture is to seperate infrastrucutre from the domain it
shouldn't be built in complete ignorance. This is one such scenario.

Although a specification is the semantically right tool, and as you
say for simple data queries serves its purpose, using it _everywhere_
may be stiving for too much 'ignorance'. The fact is a specification
is to be used against an
existing object to say "does this object satisfy my spec" which is
useful for searching collections using predicates etc.

Even though a repository behaves like a collection really its backing
a database and sometimes you have to let the domain expose some small
amount of this knowledge and accept that a specification isn't 100%
right for all
search scenarios on a database. Mainly because database's are set
based (I
don't know if object databases may support specifications). This is
why we have the Query object: it acts as an interpreter between the
language of the domain and that of the database.

Of course someone could write a powerful specification to query object
library for their project but this is a questoin of time management
and again we need to refer back to Eric's book where code that
enhances the functionality of the core domain should be prioritised
over the code that is technically clever (otherwise we risk quickly
moving back to the old software factory model). In these cases it may be
best to let the domain 'know' that its repository is querying
something rather than fufilling the illusion it is an in-memory
collection.

Of course this doesn't mean linking your NHibernate library into your
domain so you can use IQuery in your repositories.
Post by michal_talaga
By saying "I see no way" I meant the Data Mapper scenario ;-)
--
Michal
------------------------ Yahoo! Groups Sponsor --------------------~-->
Great things are happening at Yahoo! Groups. See the new email design.
http://us.click.yahoo.com/lOt0.A/hOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
michal_talaga
2007-03-08 16:08:43 UTC
Permalink
(I don't know if object databases may support specifications).
That is a good question and I'm glad you have asked it.
There is at least one ODB that can handle plain specifications in form
of predicates. Its db4o.
They call it Native Queries. Db4o is able to analyze the code of your
predicate and build a query-object like structure to perform an
optimized query.
--
Michal



------------------------ Yahoo! Groups Sponsor --------------------~-->
Yahoo! Groups gets a make over. See the new email design.
http://us.click.yahoo.com/hOt0.A/lOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
Tim McCarthy
2007-03-07 02:41:30 UTC
Permalink
Michal,

I use an implementation of the Composite Specification pattern that I
wrote
<http://blogs.interknowlogy.com/timmccarthy/archive/2007/01/22/10863.asp\
x> . The way I use them in my repositories is very similar to how LINQ
uses expressions. I either iterate through a list of things and call
IsSatisfiedBy on each thing to build a new list, or I parse the
parameters out of the specification and pass them on to a stored
procedure. In the latter case the stored procedure actually performs
the specification, but the beauty of it is that the individual
repository decides how it should work. What I think is nice about it is
that people using my repositories don't have to worry about where the
specification is executed, they just pass in their specifications.

I hope this helps.

Tim
Post by michal_talaga
Hello!
"Yet another approach for querying is to use the Specification
pattern" ... "Even those Specification classes could very well spit
out IQuery"
Those are sentences from Jimmy Nilsson's book on DDD.
As much as I like the specification pattern and the possibility to
Rository r = new Repository();
Specification s = new LongNameSpecification();
User[] users = r.GetBySpec(s);
I have simply no idea, what should I do with the specification object
when it comes to real implementation when using some kind of data
mapper or a plain sql even.
Jimmy Nilsson states that Specification can spit IQuery (some kind of
Query Object). OK. If I had IQuery i can work with it, but how do I
get it? I cannot accept coding the same logic once in the
IsSatisfiedBy method and once to spit IQuery and I have no idea how
to do it otherwise.
Any suggestions?
--
Michal
michal_talaga
2007-03-07 14:53:12 UTC
Permalink
Post by Tim McCarthy
I use an implementation of the Composite Specification pattern that I
I'm the one that asked questions on your blog in the comments under the
article on Composite Specification.
Unfortunately I still have no satisfactory answer neither here nor
anywhere else.
Question remains: how to use specifications when it comes to data
mappers.
--
Michal



------------------------ Yahoo! Groups Sponsor --------------------~-->
Great things are happening at Yahoo! Groups. See the new email design.
http://us.click.yahoo.com/lOt0.A/hOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
f***@sanofi-aventis.com
2007-03-07 09:45:33 UTC
Permalink
Michal,

I'm confronted to same problem than you and actually have no clear
answer. As you, I like the idea to give a specification to a repository
without knowing exactly what is done by the repository (a: all rows are
queried in the db and then filtered or b: a query is build upon the
specification or even c: the repository could first use a query and then
filter returned rows).

I can't figure out how the repository could build a query if the
specification only provides a IsSatisfiedBy method (as it should be).
Spiting out an IQuery is for me the unique solution.

Now, the real problem is this one : how *internally* do I implement my
specification in a way I don't have to implement IsStatisfiedBy and
GetQuery totally disconnected. I don't know if it's possible and I don't
think it's critical and if it should be done (see the hypothesis c
above). Perhaps one way could be to add the Specification interface (the
IsSatisfiedBy method) to the query class...

Hope that helps,

Fabien
Post by michal_talaga
Hello!
"Yet another approach for querying is to use the Specification
pattern" ... "Even those Specification classes could very well spit
out IQuery"
Those are sentences from Jimmy Nilsson's book on DDD.
As much as I like the specification pattern and the possibility to
Rository r = new Repository();
Specification s = new LongNameSpecification();
User[] users = r.GetBySpec(s);
I have simply no idea, what should I do with the specification object
when it comes to real implementation when using some kind of data
mapper or a plain sql even.
Jimmy Nilsson states that Specification can spit IQuery (some kind of
Query Object). OK. If I had IQuery i can work with it, but how do I
get it? I cannot accept coding the same logic once in the
IsSatisfiedBy method and once to spit IQuery and I have no idea how
to do it otherwise.
Any suggestions?
--
Michal
------------------------ Yahoo! Groups Sponsor --------------------~-->
Great things are happening at Yahoo! Groups. See the new email design.
http://us.click.yahoo.com/lOt0.A/hOaOAA/yQLSAA/NhFolB/TM
--------------------------------------------------------------------~->
Loading...