Tuesday, September 16, 2008

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

No comments: