Super Models, Part 1: Sexy Specifications

In Domain-Driven Design we turn to the specification pattern when we want to check whether an object matches some criteria. I think specification is the oft-forgotten bastard child pattern of the domain model pattern language. I know I frequently turn to queries — sometimes query objects — when I want to retrieve a set of some entity to work on.

There are some major drawbacks to using queries. Namely there’s a huge testing liability. Say we’re using a technology like LINQ or NHibernate HQL or even SQL. Well our query and its various predicates that make up our “where clause” are tied up in a single monolithic statement, each of which needs testing. We end up reach deep into the bucket of compromise to find solutions to deal with this mess. Things like object mothers and fluent fixtures help, but are in no way ideal. Wouldn’t it be great if we could create a little vocabulary where each word was verified and tested?

Well, yes, it would. And we can accomplish some of these goals by breeding the specification pattern with one of the original GoF patterns, composite. Other people have written about or demonstrated this concept (extensively) so I’ll keep my treatment lean and referential, but I’d encourage you to read on; I’ll cover a cute little trick at the end.

Sidebar: Specification is quickly challenging service or component for the title “most overloaded term in software development.” Think about it; we’ve got specifications in Behavior-Driven Development, Domain-Driven Design, and Design by Contract. To be clear I’m using specification in terms of model specifications and the practice of DDD.

Composite Specifications

Let’s start with a quick interface, and I’m assuming you’ve done the background reading on the pattern:

public interface ISpecification
{
   bool Matches(T entity);
}

In reality I’d use a generic with a constraint to be sure that “T” in our case is an IEntity. I define an IEntity for my models so I can be sure we have things like an “ID” and a “Version” and can safely but generic constraints in layer supertypes like repositories, builders, factories, etc.

Next I’ll define a base class, or layer supertype if you trend fancy, with some special methods and some nested classes. Pay attention to the “And” and “Or” with corresponding nested classes:

public abstract class Specification : ISpecification
{
   public abstract bool Matches(T entity);

   public Specification And(ISpecification specification)
   {
      return new AndSpecification(this, specification);
   }

   public Specification Or(ISpecification specification)
   {
      return new OrSpecification(this, specification);
   }

   private class AndSpecification : Specification
   {
      private readonly ISpecification left;
      private readonly ISpecification right;
      public AndSpecification(ISpecification left, ISpecification right)
      {
         this.left = left;
         this.right = right;
      }
      public override bool Matches(T entity)
      {
         return (left.Matches(entity) && right.Matches(entity));
      }
   }

   private class OrSpecification : Specification
   {
      private readonly ISpecification left;
      private readonly ISpecification right;
      public OrSpecification(ISpecification left, ISpecification right)
      {
         this.left = left;
         this.right = right;
      }
      public override bool Matches(T entity)
      {
         return (left.Matches(entity) || right.Matches(entity));
      }
   }
}

And I suppose we’ll make a sample entity and a couple specifications. These are admittedly very anemic (setters are usually work of the devil) and contrived. It’s illustrative folks!

public class Customer
{
   public decimal TotalOrders { get; set; }
   public bool Active { get; set; }
}

public class StatusSpecification : Specification
{
   private readonly bool active;
   internal StatusSpecification(bool active)
   {
      this.active = active;
   }
   public override bool Matches(Customer entity)
   {
      return entity.Active == active;
   }
}

public class TotalOrdersSpecification : Specification
{
   private readonly decimal amount;
   internal TotalOrdersSpecification(decimal amount)
   {
      this.amount = amount;
   }
   public override bool Matches(Customer entity)
   {
      return (entity.TotalOrders > amount);
   }
}

With all this in place I can now chain specifications together to achieve a composite — if not somewhat awkward and noisy — syntax. Example? Okay, sure:

var specification = 
   new TotalOrdersSpecification(42m).And(new StatusSpecification(true));

var customer1 = new Customer() { Active = false, TotalOrders = 41m};
Console.WriteLine(specification.Matches(customer1));
// False

var customer2 = new Customer() { Active = true, TotalOrders = 43m};
Console.WriteLine(specification.Matches(customer2));
// True
Console.ReadLine();

Bring the Hotness

Update Nigel Sampson describes a similar technique using lamdas and operator overloading. It’s a slightly different spin on the same problem, but he also uses the operator overloading trick for clarity. I’d encourage you to check it out; his blog is new but there’s some good stuff there already.

I have some issues with the syntax immediately above. Namely we’ve got a pretty limited means of expressing complex orders of operation in our specifications. If, in pursuit of complex expressions, we pull the AndSpecification and OrSpecification out then we get an even noisier syntax:

var specification = 
    new AndSpecification(..., ...).Or(...);

I think I can do better. If we’re pursuing the DDD goal of “the model is the code” and we’re trying to bring our model to evermore expressive heights we need to eliminate some of the parenthesis junk. We can do this by using that most magical (and dangerous) feature of C#, operator overloading.

Let’s send my specification base class to wardrobe and makeup, stat!

public abstract class SexySpecification : ISpecification
{
   public abstract bool Matches(T entity);

   private class AndSpecification : SexySpecification
   {
      private readonly ISpecification left;
      private readonly ISpecification right;
      public AndSpecification(ISpecification left, ISpecification right)
      {
         this.left = left;
         this.right = right;
      }
      public bool Matches(T entity)
      {
         return (left.Matches(entity) && right.Matches(entity));
      }
   }

   private class OrSpecification : SexySpecification
   {
      private readonly ISpecification left;
      private readonly ISpecification right;
      public OrSpecification(ISpecification left, ISpecification right)
      {
         this.left = left;
         this.right = right;
      }
      public override bool Matches(T entity)
      {
         return (left.Matches(entity) || right.Matches(entity));
      }
   }

   private class NotSpecification : SexySpecification
   {
      private readonly ISpecification specification;
      public NotSpecification(ISpecification specification)
      {
         this.specification = specification;
      }
      public override bool Matches(T entity)
      {
         return !(specification.Matches(entity));
      }
   }

   public static SexySpecification operator &(SexySpecification left, ISpecification right)
   {
      return new AndSpecification(left, right);
   }

   public static SexySpecification operator |(SexySpecification left, ISpecification right)
   {
      return new OrSpecification(left, right);
   }

   public static SexySpecification operator !(SexySpecification specification)
   {
      return new NotSpecification(specification);
   }
}

Now we have a much more natural and terse syntax. You have to use the & and | operators because you can’t overload binary operators such as && and ||. I’m OK with this; I get less line noise:

var specification = 
   new TotalOrdersSpecification(42m) & new StatusSpecification(true);

Admittedly it’s a little thing, but as we move into more complex composite specifications little differences like these really start to reduce the mental tax associated with parsing a model which, to me, is a big, big deal. And, when all is said and done, isn’t it the little things in life that really matter?

This entry was posted in .net, C#, code, DDD, design, Domain Model, DSLs, patterns, specification. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

12 Responses to Super Models, Part 1: Sexy Specifications

  1. Ollie Riches says:

    Great post and follow up comments

  2. Dave Laribee says:

    @Perry – You _can_ do that. See Nigel’s post (in the update remark above). I’d recommend against it; that’s a place where query object or something like the NH criteria API is better suited.

    Specifications are domain concepts, IMO. They shouldn’t be used to create a generic query language; you’ll dilute your domain. Also, as Ayende points out above, you’re going to most likely want to query a durable store (i.e. RDBMS).

  3. Perry Neal says:

    I’m working through this example and trying to “extend” it to make sure I understand it completely. How would you implement a GreaterThan or LessThan specification?

  4. Aaron Jensen says:

    FYI, you can enable overriding of the short circuit operators (&& and ||), just override operator true and false. See:

    http://www.blackwasp.co.uk/CSharpLogicalOpOverload.aspx

  5. Dave Laribee says:

    @Nigel – Cool technique. I marked an update linking to your post. Thanks for pointing that out!

  6. Dave Laribee says:

    @Avish – I like that distinction/terminology. I’ll be following this with at least two posts re: specifications. One will deal with the query problem.

  7. Dave Laribee says:

    @Ayende – Yes and no. Specification is useful in deciding when we should apply logic to a particular entity (orthogonal concern to query) but we can also use specifications as building blocks for queries on durable object storage. More to come on that…

  8. Avish says:

    To reiterate what Ayende said with a less confident approach: ever since hearing about specifications in your “Fundamental DDD” talk I took a liking to them. However, since most queries are against some sort of non-cached storage, I can’t see how they are useful in the common scenario.
    Do you mix in some magic ingredient that translates predicate specification into SQL, HQL, LINQ, whatever?
    What if they were Expression Tree Specifications rather than Predicate Specifications? Wouldn’t that be a little more flexible for translating them into other query interfaces?

  9. I’ve found you can reduce the building block code by using lamdas.

    http://nichestone.com/blog/08-03-15/simplifying_the_composite_specification_pattern.aspx

    Normally I wouldn’t use predicate specifications in actual code as I’ve done in the tests as I’d rather create them around business rules. However it does allow us to quickly chain them together.

  10. Ryan Gray says:

    You can use a trick to overload && and || :
    http://www.ayende.com/Blog/archive/2006/08/04/7381.aspx

    I would have linked directly to Steve’s blog, but his site appears to be down for the moment.

  11. That is useful in a very limited sense, mainly because most of the really interesting queries are against persistence storage.
    As a simple example, I want to display all the products a user is allowed to buy…

  12. Colin Jack says:

    Not tried that approach but looks good, definitely gonna give it a shot as I like operator overloading more each time I use it.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>