I'm just wondering if Specification pattern is pointless, given following example:
Say you want to check if a Customer has enough balance in his/her account, you would create a specification something like:
new CustomerHasEnoughMoneyInTheirAccount().IsSatisfiedBy(customer)
However, what I'm wondering is I can achieve the same "benefits" of Specification pattern (such as only needing to change the business rules in on place) by using Property getter in the Customer class like this:
public class Customer
{
     public double Balance;
     public bool HasEnoughMoney
     {
          get { return this.Balance > 0; }
     }
}
From client code:
customer.HasEnoughMoney
So my question really is; what is the difference between using the property getter to wrap the business logic, and creating Specification class?
Thank you all in advance!
In the general sense, a Specification object is just a predicate wrapped up in an object. If a predicate is very commonly used with a class, it might make sense to Move Method the predicate into the class it applies to.
This pattern really comes into its own when you're building up something more complicated like this:
var spec = new All(new CustomerHasFunds(500.00m),
                   new CustomerAccountAgeAtLeast(TimeSpan.FromDays(180)),
                   new CustomerLocatedInState("NY"));
and passing it around or serializing it; it can make even more sense when you're providing some sort of "specification builder" UI.
That said, C# provides more idiomatic ways to express these sorts of things, such as extension methods and LINQ:
var cutoffDate = DateTime.UtcNow - TimeSpan.FromDays(180); // captured
Expression<Func<Customer, bool>> filter =
    cust => (cust.AvailableFunds >= 500.00m &&
             cust.AccountOpenDateTime >= cutoffDate &&
             cust.Address.State == "NY");
I've been playing around with some experimental code that implements Specifications in terms of Expressions, with very simple static builder methods.
public partial class Customer
{
    public static partial class Specification
    {
        public static Expression<Func<Customer, bool>> HasFunds(decimal amount)
        {
            return c => c.AvailableFunds >= amount;
        }
        public static Expression<Func<Customer, bool>> AccountAgedAtLeast(TimeSpan age)
        {
            return c => c.AccountOpenDateTime <= DateTime.UtcNow - age;
        }
        public static Expression<Func<Customer, bool>> LocatedInState(string state)
        {
            return c => c.Address.State == state;
        }
    }
}
That said, this is a whole load of boilerplate that doesn't add value!  These Expressions only look at public properties, so one could just as easily use a plain old lambda!  Now, if one of these Specifications needs to access non-public state, we really do need a builder method with access to non-public state.  I'll use lastCreditScore as an example here.
public partial class Customer
{
    private int lastCreditScore;
    public static partial class Specification
    { 
        public static Expression<Func<Customer, bool>> LastCreditScoreAtLeast(int score)
        {
            return c => c.lastCreditScore >= score;
        }
    }
}
We also need a way to make a composite of these Specifications - in this case, a composite that requires all children to be true:
public static partial class Specification
{
    public static Expression<Func<T, bool>> All<T>(params Expression<Func<T, bool>>[] tail)
    {
        if (tail == null || tail.Length == 0) return _0 => true;
        var param = Expression.Parameter(typeof(T), "_0");
        var body = tail.Reverse()
            .Skip(1)
            .Aggregate((Expression)Expression.Invoke(tail.Last(), param),
                       (current, item) =>
                           Expression.AndAlso(Expression.Invoke(item, param),
                                              current));
        return Expression.Lambda<Func<T, bool>>(body, param);
    }
}
I guess part of the downside to this is it can result in complicated Expression trees.  For example, constructing this:
 var spec = Specification.All(Customer.Specification.HasFunds(500.00m),
                              Customer.Specification.AccountAgedAtLeast(TimeSpan.FromDays(180)),
                              Customer.Specification.LocatedInState("NY"),
                              Customer.Specification.LastCreditScoreAtLeast(667));
produces an Expression tree that looks like this.  (These are slightly formatted versions of what ToString() returns when called on the Expression - note that you wouldn't be able to see the structure of the expression at all if you had only a simple delegate!  A couple of notes: a DisplayClass is a compiler-generated class that holds local variables captured in a closure, to deal with the upwards funarg problem; and the dumped Expression uses a single = sign to represent equality comparison, rather than C#'s typical ==.)
_0 => (Invoke(c => (c.AvailableFunds >= value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass0).amount),_0)
       && (Invoke(c => (c.AccountOpenDateTime <= (DateTime.UtcNow - value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass2).age)),_0) 
           && (Invoke(c => (c.Address.State = value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass4).state),_0)
               && Invoke(c => (c.lastCreditScore >= value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass6).score),_0))))
Messy! Lots of invocation of immediate lambdas and retained references to the closures created in the builder methods.  By substituting closure references with their captured values and β-reducing the nested lambdas (I also α-converted all parameter names to unique generated symbols as an intermediate step to simplify β-reduction), a much simpler Expression tree results:
_0 => ((_0.AvailableFunds >= 500.00)
       && ((_0.AccountOpenDateTime <= (DateTime.UtcNow - 180.00:00:00))
           && ((_0.Address.State = "NY")
               && (_0.lastCreditScore >= 667))))
These Expression trees can then be further combined, compiled into delegates, pretty-printed, edited, passed to LINQ interfaces that understand Expression trees (such as those provided by EF), or what have you.
On a side note, I built a silly little micro-benchmark and actually discovered that closure reference elimination had a remarkable performance impact on the speed of evaluation of the example Expression when compiled to a delegate - it cut the evaluation time nearly in half(!), from 134.1ns to 70.5ns per call on the machine I happen to be sitting in front of.  On the other hand, β-reduction made no detectable difference, perhaps because compilation does that anyway.  In any case, I doubt a conventional Specification class set could reach that kind of evaluation speed for a composite of four conditions; if such a conventional class set had to be built for other reasons such as the convenience of builder-UI code, I think it would be advisable to have the class set produce an Expression rather than directly evaluate, but first consider whether you need the pattern at all in C# - I've seen way too much Specification-overdosed code.
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