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.