What is the difference between the Query Object pattern proposed by Martin Fowler and the Specification pattern proposed by Eric Evans?
Fowler's Query Object pattern (Patterns of Enterprise Application Architecture p. 316) is a specialization of the Interpreter pattern that allows database queries to be presented in domain language. An example mostly from Fowler:
QueryObject query = new QueryObject(Person.class);
query.addCriteria(Criteria.greaterThan("numberOfDependents", 0))
List<Person> persons = query.execute(unitOfWork);
The Java Persistence API Criteria API and Rails' ActiveRecord query interface are examples of this pattern.
Evans' Specification pattern (Domain-Driven Design p. 224) implements a business rule as an object representing a predicate on another object, an entity or value object. Evans' example is an InvoiceDelinquency
object with a boolean method test(Invoice)
which returns true if the Invoice
is delinquent. A Specification can be used for several things: validating an object, querying a collection or specifying how a new object is to be created.
Specification is essentially the same as the Criteria class that is part of the Query Object pattern. The Query Object description didn't intend Criteria to have any other purpose than specifying queries, but if you used both patterns in the same program you'd certainly want to use your Specifications as your Query Objects' Criteria.
Implementations of the Specification pattern tend to be more narrow. They answer a specific question that is related to your domain. For example, this spec is fully devoted to whether or not some movie is good for kids:
var spec = new MovieForKidsSpecification();
if (!spec.IsSatisfiedBy(movie))
return Error(“The movie is not eligible for children”);
Query Object is a more broad pattern and can be used not only for answering questions your domain model poses. You can look at Query Object as a super-set of Specifications. Here's an example of implementing the Specification pattern in my blog: Specification pattern implementation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With