Query Objects and the Specification Pattern

posted on 10/07/08 at 10:55:44 pm by Joel Ross

The other night, I had an eye opening moment when I finally understood how I could use query objects to allow me to use a generic repository, yet still be able to have re-usable queries. But one thing I didn't quite get was how this related to the Specification pattern. The samples I found (including the one I linked to) all used the term Specification, but that wasn't how I understood the specification pattern to work.

But just by adding one method to the base class, it (again) became clear how the two are related:

   1:  public bool IsSatisfiedBy(T candidate)
   2:  {
   3:    return SatisfyingElementsFrom(new[] { candidate }.AsQueryable()).Any();
   4:  }

By adding this, you can now pass an entity to it, and determine if that entity satisfies the specification. As a result, I've renamed my base class to SpecificationBase<T>, and can now use them for validation purposes as well.

Now, the next question. Does this violate the Single Responsibility Principle? At first glance, I thought it did, because it's used to do two different things: query and validate. But taking a closer look, I don't think it does. How it's used externally is different than what it does internally - which is check that a collection of entities (even if the collection is only one element) satisfies a given specification. More to the point, it's single reason for change would be if there was a change to how it determines that an entity meets the specification. That isn't related to querying or validating at all - that's above this layer.

Of course, I could be wrong. In your opinion, does this violate SRP? If so, how would you fix it?

Tags: | |

Categories: Development, C#