I'm doing some R&D work, and as such am exploring design patterns. I have recently been reading up on the Specification pattern and was referred to this great article.
I was intrigued by the simplicity and cleanliness of the code, but i started to draw some comparisons to implementing the same cleanliness using other techniques.
Consider the following interface contract for a service layer:
public interface IFooDataService
{
ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification);
ICollection<Foo> GetFooByPredicate(Func<Foo,bool> predicate);
ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs);
}
So, some initial points:
Now, onto the implementation:
public ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification)
{
return fooDataRepository
.Find()
.Where(f => specification.IsSatisfiedBy(f))
.ToList();
}
public ICollection<Foo> GetFooByPredicate(Func<Foo, bool> predicate)
{
return fooDataRepository
.Find()
.Where(predicate)
.ToList();
}
public ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs)
{
return fooDataRepository
.Find()
.WhereMeetsSearchCriteria(searchArgs)
.ToList();
}
Points on the implementation:
So, that being said, under what conditions would you use one of above 3 techniques?
My thoughts on Specification Pattern:
My thoughts on Extension Methods (Pipes & Filters):
My thoughts on Predicate Method:
My final thought logic is that if you are working on a complex business application where business requirements are known up front but may change over time, then i would use Specification pattern.
But for a application that is a "startup", ie requirements will evolve over time and has a multitude of ways to retrieve data without complex validation, i would use the Pipes and Filters methods.
What are your thoughts? Have any of you run into problems with any of the above methods? Any recommendations?
About to start a new project so these types of considerations are critical.
Thanks for the help.
EDIT for Clarification on Specification pattern
Here is same usage of the Specification pattern.
Specification<Foo> someSpec; // Specification is an abstract class, implementing ISpecification<TEntity> members (And, Or, Not, IsSatisfiedBy).
someSpec = new AllFoosMustHaveABarSpecification(); // Simple class which inherits from Specification<Foo> class, overriding abstract method "IsSatisfiedBy" - which provides the actual business logic.
ICollection<Foo> foos = fooDataService.GetFoosBySpecification(someSpec);
From my little experience :
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