"Not" Specification

I am currently spiking out a DDD based solution that will have a significant amount of rules associated. I am currently making heavy use of the Specification pattern as there is a tonne of reuse from these and potentially a more readable API. One problem I have and have always had with the typical Specification pattern is the Not() method; It is a bit ugly and when used in method chaining is somewhat confusing as the Not is a suffix, unlike the other methods in the fluent interface (And and Or).

I have made a slight change to my base specification class by adding an AndNot(x) method as I quite frequently am finding the need for it and it is so much more readable than And(x).Not().

This is simply an addition of the signature on the interface:

public interface ISpecification
{
bool IsSatisfiedBy(T candidate);

ISpecification And(ISpecification other);

ISpecification AndNot(ISpecification other);//NEW!!!

ISpecification Or(ISpecification other);

ISpecification Not();
}

and the implemented code is just:

public ISpecification AndNot(ISpecification other)
{
return new AndSpecification(this, new NotSpecification(other));
}

I don’t see a need to remove the Not() as it is still useful in defining reusable not specs.

HTH
Rhys

Refactoring to Specification Pattern and Predicates

Code like this doesnt mean anything:

public bool CanBePulled

{

get

{

bool canPull = false;

if (this.IsOnPlatform)

{

IJobItemStatus status = this.jobItemStatus;

if (status != null)

{

canPull =

!status.IsDeliveringToChops &&

!status.IsDeliveringToPlatform &&

!status.IsPullingFromChops &&

!status.IsCancelled &&

!status.IsPulled &&

!status.IsPullRequested &&

!status.IsRetired;

}

}

return canPull;

}

}

It just lists a bunch of boolena properties that dont relay why we care about this fields. Althought the follow syntactically could do with some reshuffling i think the underlying business intent is much more easily convey:

public bool CanBePulled

{

get

{

AbleToPull spec = new AbleToPull();

return spec.IsSatisfiedBy(this);

}

}

using the private specification class

private class AbleToPull : CompositeSpecification

{

public override bool IsSatisfiedBy(JobItem candidate)

{

ISpecification ableToPull = new OnPlatfrom().And(new HasProcessed().Not());

return ableToPull.IsSatisfiedBy(candidate);

}

}

Here it is now obvious that “To be pulled” you need to be “On Platform” and “Not Processed”. To me this conveys much more bussiness intent and therefore becomes much more usable to the developer consuming or maintaining the API

http://en.wikipedia.org/wiki/Specification_pattern

UPDATE: i hate office as my blog poster… WLW is no functional at work eitehr, so sorry about he nasty formating… it kinda defeats the purpose of the post