Home > Design Patterns, dotnet 4, SOLID > Composite Pattern

Composite Pattern

This post is continuation of my previous post on Specification Pattern and in this post we will see how we can chain these Specifications (the interface) to build more complex rule with help of Composition.

First lets see the pattern statement

The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to “compose” objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

The reason why we choose composition is that the interface we define in our Specification looks like a Predicate i.e. it takes an object as argument and returns a Boolean so if we chain multiple specification together it should still return a Boolean i.e. multiple specification can be together to yield whether the compound condition is true or not.

Lets look at three possible ways to combine these condition :-

  1. And Specification
  2. Or Specification
  3. Not Specification

And lets add the above three specification to our ISpecification interface we created in the Specification Pattern post.

public interface ISpecification<T>
{
    bool IsSatisfiedBy(T candidate);
    ISpecification<T> And(ISpecification<T> other);
    ISpecification<T> Or(ISpecification<T> other);
    ISpecification<T> Not();
}

Now you can see how we are composing things together, in the interface since all the other specification have the same signature and the same return type we can combine them together without breaking the contract(interface) and this is the core principle of Composite Pattern.

Lets write a class which will implement this interface and will help us compose specifications.

public abstract class CompositeSpecification<T> : ISpecification<T>
{
    public abstract bool IsSatisfiedBy(T candidate);

    public ISpecification<T> And(ISpecification<T> other)
    {
        return new AndSpecification<T>(this, other);
    }

    public ISpecification<T> Or(ISpecification<T> other)
    {
        return new OrSpecification<T>(this, other);
    }

    public ISpecification<T> Not()
    {
        return new NotSpecification<T>(this);
    }
}

The important thing is that since the class has been designed using Generics it can be applied to any class. Lets write code for each of these Condition Specification.

public class AndSpecification<T> : CompositeSpecification<T>
{
    private readonly ISpecification<T> left;
    private readonly ISpecification<T> right;

    public AndSpecification(ISpecification<T> left, ISpecification<T> right)
    {
        this.left = left;
        this.right = right;
    }

    public override bool IsSatisfiedBy(T candidate)
    {
        return left.IsSatisfiedBy(candidate) && right.IsSatisfiedBy(candidate);
    }
}
public class NotSpecification<T> : CompositeSpecification<T>
{
    private readonly ISpecification<T> other;

    public NotSpecification(ISpecification<T> other)
    {
        this.other = other;
    }

    public override bool IsSatisfiedBy(T candidate)
    {
        return !other.IsSatisfiedBy(candidate);
    }
}
public class OrSpecification<T> : CompositeSpecification<T>
{
    private readonly ISpecification<T> left;
    private readonly ISpecification<T> right;

    public OrSpecification(ISpecification<T> left, ISpecification<T> right)
    {
        this.left = left;
        this.right = right;
    }

    public override bool IsSatisfiedBy(T candidate)
    {
        return left.IsSatisfiedBy(candidate) 
                  || right.IsSatisfiedBy(candidate);
    }
}

Lets visualize it in a class diagram and see all the code we have written so far.

Composite Pattern

Lets modify the ApplicationLoanSpecification class we created in the previous post to implement the CompositePattern class.

public class ApplicantLoanSpecification : CompositeSpecification<Applicant>
{
    public override bool IsSatisfiedBy(Applicant candidate)
    {
        return (candidate.CreditRating == 10 && candidate.TotalEquity > 45000);
    }
}

So far nothing has change drastically and now we will start creating some more specifications.

public class SalarySpecification : CompositeSpecification<Applicant>
{
    public override bool IsSatisfiedBy(Applicant candidate)
    {
        return (candidate.Salary > 100000);
    }
}
public class AgeSpecification : CompositeSpecification<Applicant>
{
    public override bool IsSatisfiedBy(Applicant candidate)
    {
        return (candidate.Age < 80);
    }
}

So here I just created some fictitious conditions to create a real life complex business rules, the important thing is that because of using the pattern each of my class are very small and very specific(pardon the pun). And it’s another good example of Single Responsibility principle.Lets put it all together in our Applicant class and see how the method chaining looks like.

public class Applicant
{
    public Int32 Id { get; set; }
    public Int32 Age { get; set; }
    public Int32 CreditRating { get; set; }
    public decimal TotalEquity { get; set; }
    public decimal Salary { get; set; }

    private readonly ISpecification<Applicant> isQualifiedForLoan;
    private readonly ISpecification<Applicant> salaryIsQualified;
    private readonly ISpecification<Applicant> ageIsLessthanEighty;

    public Applicant()
    {
        isQualifiedForLoan = new ApplicantLoanSpecification();
        salaryIsQualified = new SalarySpecification();
        ageIsLessthanEighty = new AgeSpecification();

    }
    public bool CanApplyForLoan()
    {
        var canApplyForLoan = isQualifiedForLoan.
                               And(salaryIsQualified.
                               And(ageIsLessthanEighty));

        return canApplyForLoan.IsSatisfiedBy(this);
    }
}

You can see how our applicant business object encapsulates the business logic but have a nice separation of concern with these specifications. Also you might have noticed that the method chaining is done through a fluent interface.The whole condition can be read as “Is Qualified for Loan and Salary is qualitified and Age is less than Eighty”.

Lets see how we will invoke our applicant class from outside and I know I should have written a unit test, but hey its a blog post and sometimes even I feel lazy ;-).

static void Main(string[] args)
{
    var applicant = new Applicant()
                        {
                            Salary = 150000,
                            Age = 25,
                            CreditRating = 10,
                            TotalEquity = 55000
                        };

    Console.WriteLine("Can apply for loan:{0}",applicant.CanApplyForLoan());
    Console.ReadKey();
}

And when we run the program we get a true result as this applicant instance does satisfy all the conditions.I encourage you to get a full depth of this concept and try experiment with other Specification like the “Or” and “Not”. If you have any problem understanding or chaining other specification please feel to get in touch with me.

Last but not the least if you are designing any layered application/core framework for your application,it will be great if you can provide a nice fluent interface to other programmers.

Advertisements
  1. Ruth Frasca
    June 8, 2011 at 3:47 pm

    I believe this web site contains some real excellent information for everyone : D.

    • June 10, 2011 at 10:30 pm

      Hi Ruth,
      Thanks and I hope you enjoy the content of my blog and it’s adding value to your coding/projects.

  2. June 10, 2011 at 12:17 pm

    fluent and nice. very easy to understand as usual from you.

  3. Mahendra Nepali
    June 23, 2011 at 5:12 pm

    Kool composite stuff. I think I can use this to implement the dynamic formula builder for my application. Thanks for the wonderful post.

    • June 23, 2011 at 8:34 pm

      Hi Mahendra,
      Thanks for your comment and I am glad that I could ad value to your dynamic formula builder. Sounds like an interesting solution.Are you by any chance the same Mahendra with whom I have worked in Pune ?

  4. Mahendra
    June 24, 2011 at 2:33 pm

    Hi Prash,
    Yes I am the same Mahendra. Good to see your blog. Excellent stuff. Infact when I read your next post using Expressions my job was simple. Thanks once again.

  5. Alex
    July 29, 2011 at 3:00 pm

    very useful.
    your contribute is gold.

    • August 1, 2011 at 9:17 am

      Hi Alex,
      Thanks a lot for your nice comment and I hope to continue to blog whatever i learn.

  6. Cali LaFollett
    February 12, 2012 at 4:36 pm

    Excellent post! Very easy to read and understand.

    I’ve read the Eric Evans “Blue Book” and have done quite a bit of studying on the subjects of Specifications and Repositories and how to utilize these with LINQ and ORMs. What you have here definitely reflects the simplistic goals Eric presented.

    I do have one question for you. I noticed you added the composing And, Or, and Not methods directory to the ISpecification interface. Would it have made more sense to name the abstract CompositeSpecification class to just Specification instead?

    If this would not be acceptable, my other thought would be to create an ICompositeSpecification interface deriving from ISpecification and which then adds the And, Or, and Not methods. Each composing method could still take an ISpecification but return an ICompositeSpecification reference.

    Although doing this adds a new level of inheritance, it aids in clearly defining the composition part of a CompositeSpecification.

    Thoughts??

    P.S. Keep up the great work!

  1. June 21, 2011 at 12:15 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: