I’m a guy who loves many of the new patterns that I get to know. But sometimes when I show that pattern to colleagues around me, they tilt their heads and say: „Arrrm, who needs this?“. Often they help me to get back to the ground and think again about intents and benefits of one or the other pattern.
Currently I’m rethinking the Specification Pattern, which has been introduced by Eric Evans and Martin Fowler some time ago and got some attention in the DDD community and beyond. The intent of the Specification Pattern is to separate the logic for (e.g.) filtering an entity from the entity itself. This responsibility is encapsulated in single classes – the specifications. Those specifications are given for example to a single method Filter()
on a repository, which takes care of filtering the domain model by the specifications. Thus, you bypass the need for having several special methods in your repository which take care of the actual filter operation (such as FilterByCustomerName()
, FilterByCustomerAddress()
etc.).
An example interface snippet for a repository of persons with a specification filter method could then be:
interface IPersonRepository { IEnumerable<Person> Filter(ISpecification<Person> filterTerm); // ... }
Summarized, some key benefits of the Specification Pattern are:
- Loose coupling of the filter logic from the objects being filtered,
- Single responsibility: Interface of repository/data provider isn’t polluted with lots of filter methods,
- Callers can express in a flexible way by which criteria entities can be filtered,
- Composition of specifications (e.g. by a fluent interface) yields to flexible filter queries, for example:
[sourcecode language=’c#‘]var filter = Filter.By (25).And („Frankfurt“)[/sourcecode]
But now the provocative question that one could come with: Who needs the Specification Pattern in times of C# 3.0 and Expressions? This might sound disturbing at first, but let me explain…
C# 3.0 came up with the new concept of Expressions/Expression trees. This way, code can be treated as a kind of syntax tree in the program. Developers can extend the tree with additional code portions and then compile it into executable code which can be invoked.
Therefore Expressions seem to give us similar benefits for filtering as specifications do. By using Expressions, we are able to define a single Filter()
method on the repository, which gets an appropriate Expression as argument. Consumers of the repository can call this method with their custom filter Expressions and thus we’ve got the same benefits: loose coupling of filter logic and objects to be filtered, flexibility for callers to provide custom filter criteria and the possibility to combine several filter criteria (several Expressions).
One could argue that with specifications we’ve got better encapsulation of the filter logic into separate classes. But this can be done with Expressions as well (e.g. by separate wrapper classes or dedicated Expression providers), so that isn’t a good argument…
The interface of a repository of persons with a filter that uses Expressions might look like this:
interface IPersonRepository { IEnumerable<Person> Filter(Expression<Predicate<Person>> filterTerm); // ... }
This leads again to the question: Do we still need the Specification Pattern or is it already embedded with Expressions in the language (C# 3.0) itself?
Pattern focus
First I want to mention that the intent of a pattern is not (only) to provide a technical solution, but also a conceptual guideline for a problem at hand. Thus Expressions as technical solution don’t cover the intent of the Specification Pattern. The Specification Pattern can be implemented with the help of Expressions, but that’s another point. So, directly comparing the Specification Pattern with Expressions is like an apple-pear-comparison.
Encapsulation focus
Let’s come to use cases when I would prefer the use of dedicated specification classes rather than directly using Expressions.
First as a team lead you could want to enforce the use of dedicated specification classes in your development team (thus enforce encapsulation of the filter logic). By giving Expressions or Predicates to filter methods directly, developers would be allowed to define filter expressions whereever they want to. You don’t have the control over this process and please don’t trust your project guidelines: If developers are allowed to do something wrong, they will do.
With specifications you can force your team members to write specification classes for their requirements, which leads to enforced encapsulation. Furthermore you drive reuse of existing specification classes. Other developers are encouraged to use existing specifications, especially because of the additional effort for writing new specifications. By combining several specifications, the reusability aspect is pushed even more.
Domain model focus
Giving consumers the full flexibility of defining custom filter criteria with specifications can be very handsome in many situations. However, in other scenarios instead of giving full flexibility, you may want to restrict the set of filters for your domain model. If you focus on your domain, you perhaps want a restricted set of specifications, each with a very specific meaning in your domain! Binding such specifications to your domain model makes the purpose of your domain and how it can/should be used in terms of filtering much clearer.
Technically, in order to restrict access to a particular set of specifications, you could create sealed specification classes inside of your domain model services (same layer as repository). Consumers of the repository would be allowed to call the Filter()
method on the repository with those specifications (and compositions of those), but they would not be able to create new specifications if you don’t mark the specification interface as public. This way you get two characteristics: Restricted filtering, which fits into your domain and your use cases on the one hand, and encapsulation/separation of filter logic and entities which should be filtered on the other hand.
Bottom line
This article started with an interesting and provocative question: Is the Specification Pattern obsolete? This question came up with a look at Expressions in C# 3.0. Technically you can achieve similar results when using Expressions instead of implementing the Specification classes by hand. But as the last sections have shown, in my opinion the Specification Pattern is not obsolete! As pattern it’s adding very specific value to the plain technical solution, when you take encapsulation and domains into account. Then it clearly goes beyond the technical aspect which many developers see at first sight.
Those are my current thoughts on specifications, but of course my opinions are not carved in stone. What do you think? What points I’ve missed perhaps? I’m eager for your comments!