Click here to Skip to main content
Click here to Skip to main content

Composed LINQ Queries using the Decorator Pattern

By , 28 Jun 2010
 

Contents

Introduction

This article series will explore practical uses and applications of design patterns in day to day development practices, using practical examples in C#. The first article (one of hopefully many more to come) will cover the Decorator Pattern. This series is also published on my Blog C# | B# | Stay# [^] which as its name implies celebrates the #-ness in all things!

Background and Concepts

Let’s kick off this post with some theory. According to the GoF, the intent of the decorator design pattern is to:

"Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."

That was quoted from their seminal work Design Patterns: Elements of Reusable Object-Oriented Software [^] In my humble opinion, one of the greatest pleasures working in software development is when we can successfully implement a pattern, not through a premeditated intent but through natural and organic development of the code at hand. We spot the variation and try to encapsulate it and then lo and behold, we end up using one pattern or another fulfilling its intent and purpose.

I think the holy grail of OO software developers (a slightly conceited statement perhaps) is to identify what is common and what varies in any given requirement and then find a way to encapsulate that change making future (and almost inevitable requirement changes) relatively easy to implement.

After that brief techno-rant, we can go back to our main topic. The Decorator Design Pattern. Conceptually, here is how the pattern looks like:

decorator_pattern.jpg

The decorator pattern allows me to create a chain of objects (trail of decorator objects) namely, the decorators that are responsible for the new functionality, and ends with the original object. And the call chain looks like:

CallChain.jpg

This is not to be confused with a linked list. Rather it should be regarded as a collection of optional decorating objects.

A Classic Example

One classic example of this pattern is the stream I/O library. For any particular stream, there is only one input, but there can be zero or more actions to perform on the input stream.

For instance, as in the example below, I can read from a memory stream, filter the stream and then read it using a custom stream reader. All these components (the later two are custom objects) implement the stream abstract class and accept a stream object in their constructors. The chain of calls looks like this:

Stream filteredMemoryStream = new StreamReader(new StreamFilter(new MemoryStream()));

Query Decorators

Personally, I use the decorator pattern to solve the problem of decomposing LINQ queries into more granular and reusable parts. A client can call several LINQ queries that are similar but only have minor variations. The direct result of this is LINQ code duplicated in every query. Another side effect is the tight coupling between the calling client and query composition.

The fictitious example I use here assumes we're querying an Employees repository and there are multitude of queries that might contain the same expressions and clauses. Say, we need to get all employees who are managers. Another requirement is that we get all employees who are managers and of certain age. We may then need to get the top %20 of those managers. All these extra queries are transformed into reusable decorators as follows:

QueryDecorator.png

As a direct result of this design, the query composition can be chained inside a factory that instantiates the desired query based on simple conditional logic of perhaps some configuration file:

public class EmployeeQueryFactory
    {
        public static QueryComponent<Employee> GetQuery()
        {            
            /*             
             * We decouple the calling client from the query component instantiation
             * by using this factory method where we encapsulate all conditional       
             * logic that determines which query component to instantiate 
             */

            //Get all employees who are contractees            
            return new ContracteesQuery(new EmployeeQuery());            
            
            //Or get all managers older than 50             
            return new AgeLimitQuery(new ManagersQuery(new EmployeeQuery()), 50);       
            
            //Or get top %20 of all contractees older than 30
            return new Top20PercentQuery(new AgeLimitQuery
		(new ContracteesQuery(new EmployeeQuery()), 30));
        }
    }

And just to add more clarity to the example at hand, I add a simple implementation of the QueryComponent and QueryWrapper respectively, along with a concrete implementation of each.

public abstract class QueryComponent<T>
{
    public abstract IQueryable<T> Query();
}

public class EmployeeQuery : QueryComponent<Employee>
{
    public override IQueryable<Employee> Query()
    {
        return new EmployeesRepository().GetAllEmployess().AsQueryable();
    }
}

public abstract class QueryWrapper<T> : QueryComponent<T>
{
    protected readonly QueryComponent<T> QueryComponent;
    protected QueryWrapper(QueryComponent<T> queryComponent)
    {
        QueryComponent = queryComponent;
    }

    protected IQueryable<T> CallTrailer()
    {
        return null != QueryComponent ? QueryComponent.Query() : null;
    }
}

public class ContracteesQuery : QueryWrapper<Employee>
{
    public ContracteesQuery(QueryComponent<Employee> queryComponent)
        : base(queryComponent)
    {
    }

    public override IQueryable<Employee> Query()
    {
        return CallTrailer().Where(p => p.IsContractee);
    }
}

Lastly, as with every post. I leave you with this quote by Christopher Alexander [^]:

"We are searching for some kind of harmony between two intangibles: a form which we have not yet designed and a context which we cannot properly describe."

Code well and Stay#!

Downloads

Here is a sample VS 2008 SP1 project that contains the query wrapper example. It is a console application that executes a sample query from the EmployeeQueryFactory.

History

  • 27 June 2010 - First version submitted
  • 28 June 2010 - Added source code example

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Anas Karkoukli
Architect
Canada Canada
Member
MCP, MCAD .NET
 
Blog: C# | B# | Stay#

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionVery Nice. But what advantage does it have over the Specification pattern?memberjacwak13 Jul '10 - 20:53 
Or is it some implementation of that pattern?
AnswerRe: Very Nice. But what advantage does it have over the Specification pattern?memberAnas Karkoukli15 Jul '10 - 3:18 
Thanks for reading the article and your feedback. the inheritance hierarchy in both the decorator and the specification patterns are exactly the same. Historically, the decorator pattern preceded the specification in the Gang of Four famous patterns book. The specification pattern is a reincarnation of the decorator pattern, which was popularized in Eric Evans books about Domain Driven Design.
 
Both patterns solve the idea of chaining and combining rules or functions. The reason behind my choice in which terminology to use is due to the fact that I was thinking in terms of function wrappers, rather than combinable business rules. So I choose to use the classic nomenclature.
 
Hope this helped.
Anas Karkoukli -- MCAD .NET
"Felix qui potuit rerum cognescere causas."

GeneralMy vote of 4memberachuki128 Jun '10 - 20:34 
Nice article
GeneralMy vote of 5memberSergio Romero28 Jun '10 - 10:07 
I tried it out and works beautifully. This will make so much duplication of code dissapear from my project it's fantastic.
GeneralRe: My vote of 5memberAvijit_Das28 Jun '10 - 13:36 
I have been thinking along the line of having re-usable expressions for the current EF project I'm working on, but I like this approach much more.
Excellent article.
GeneralRevision Reqd.memberMunim Abdul27 Jun '10 - 20:58 
Very nice, but could be an understanding problem for newbie guys.
GeneralRe: Revision Reqd.memberBaconbutty28 Jun '10 - 4:43 
It's all geek to me.
 
This is the problem with Design Patterns as I see it.... with all examples not just this one I hasten to add.
 
I've yet to see a simple real world example that goes through the code in a Design Pattersn for Dummies style.They start off with that intention but rapidly disappear in a plethora of classes and all simplicity/comments etc are lost in an assumption that the reader can leap from a short description to a hefty piece of code.
GeneralRe: Revision Reqd.memberSergio Romero28 Jun '10 - 10:15 
The way I see it, from what you wrote, you still need to study quite a bit your object oriented basics in order to understand patterns.
 
Maybe (and I'm sorry to advertise another site here) you could go to www.c-sharpcorner.com and look for articles written by Matthew Cochran. He gives very simple explanations of quite a few patterns. If you're not able to understand them, then you really need to study about interfaces, abstract classes, inheritance and polymorphism to get them.
 
I wouldn't get discourage though, personally it took me several tries of reading articles over and over before I could actually use them in my everyday coding.
 
Good luck.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 28 Jun 2010
Article Copyright 2010 by Anas Karkoukli
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid