Monday, August 10, 2009

A Better Pipeline

As a follow-up to my Pipeline and Yield in C# post from a few days ago, I just realized I can make a slightly better pipeline.

First, taking the base class for a node and changing this:

public void Register(IPhrase nextPhrase)
{
    _nextPhrase = nextPhrase;
 
}

To this ...

public void Register(IPhrase nextPhrase)
{
    if (_nextPhrase == null)
    {
        _nextPhrase = nextPhrase;
    }
    else
    {
        _nextPhrase.Register(nextPhrase);
    }
}

Then allows me to take loading up the pipeline from this:

public static string Execute(bool spanish, bool goodbye)
{            
    IPhrase root = null;
    IPhrase previous = null; 

    foreach(IPhrase phrase in _GetPhrase(spanish, goodbye))
    {
        if (root == null)
        {
            root = phrase;
        }
        else
        {
            previous.Register(phrase);
        }
        previous = phrase;
    }

    return root == null ? string.Empty : root.Execute(string.Empty);
}

To this...

public static string Execute(bool spanish, bool goodbye)
{            
    IPhrase root = null;
    
    // load up the pipeline
    foreach(IPhrase phrase in _GetPhrase(spanish, goodbye))
    {
        if (root == null)
        {
            root = phrase;
        }
        else
        {
            root.Register(phrase);
        }                
    }

    return root == null ? string.Empty : root.Execute(string.Empty);
}

Notice that I don't have to keep track of "previous" anymore. As long as I know the root (which I need to know anyway, because that's what starts the pipeline going), any registration simply follows down the links until there is a free space and attaches there.

Also a good note from my architecture mentor ... this example builds the pipeline every time. A more efficient implementation would realize there are 4 valid states and build the 4 states ahead of time and reuse them, rather than build out the entire pipeline every call.

Jeremy Likness