Following pattern is very use full decupling intermediate functionalities in between two domains.
Thanks shanka (My team member) for valuable contribution on research
Cheers!!!!
Continuing our series on Domain Driven Design, we now get to one of the more interesting patterns in DDD – the Specification.
A Specification is, in simple terms, a small piece of logic that sits on it’s own and gives an answer to a simple question … “does this match?”
With a Specification we split the logic of how a selection is made, away from the thing we are selecting.
We have a Customer, and we want to be able check if they are eligible for a discount on a Product.
If we were to put a method on the Customer entity, for example .IsEntitledToDiscountPrice(Product) we start to couple our entities tightly together, and as the number of questions we want to ask of our entity increases, the more polluted its interface becomes.
To avoid this we can use a Specification.
Some Code – A First for the Series
The basic implementation of Specification has a single method .IsSatisifiedBy, in our Discount example above we may have a EligibleForDiscountSpecification, the method would be .IsSatisifiedBy(Customer c)
The actual Specification is variable in how it is defined, but a very simple version for this scenario would be:
public interface ISpecification{ bool IsSatisfiedBy(T sut); } public class EligibleForDiscountSpecification : ISpecification<Customer> { private readonly Product _product; public EligibleForDiscountSpecification(Product product) { _product = product; } public bool IsSatisfiedBy(Customer customer) { return (_product.Price < 100 && customer.CreditRating >= _product.MinimumCreditRating); } }
This now simplifies selection or matching, and the Customer and Product are no longer coupled – our Specification now knows how to decide if the Customer is eligible for a discount. Ignoring the fact that the following is a rotten unit test, we can use our Specification like this:
[Fact] public void TestSpecification() { var product = new Product() { MinimumCreditRating = 3, Price = 50 }; var spec = new EligibleForDiscountSpecification(product); var goodCustomer = new Customer() { CreditRating = 3 }; var badCustomer = new Customer() { CreditRating = 1 }; Assert.True(spec.IsSatisfiedBy(goodCustomer)); Assert.False(spec.IsSatisfiedBy(badCustomer)); }
Two things become very easy when using Specification – we can easily select from lists and we can pass dependencies without creating coupling.
Extracted from - http://devlicio.us/blogs/casey/archive/2009/03/02/ddd-the-specification-pattern.aspx
No comments:
Post a Comment