Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences Between Query Object and Specification Patterns

What is the difference between the Query Object pattern proposed by Martin Fowler and the Specification pattern proposed by Eric Evans?

like image 532
Ibrahim Najjar Avatar asked May 28 '13 20:05

Ibrahim Najjar


2 Answers

Query Object

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.

Specification

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.

The difference

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.

like image 184
Dave Schweisguth Avatar answered Sep 24 '22 05:09

Dave Schweisguth


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

like image 23
Vladimir Avatar answered Sep 24 '22 05:09

Vladimir