I've been reading The Pragmatic Programmer for a few days and I've come across a reference to the strategy pattern. Looked it up in Design Patterns and figured I could refactor a piece of code I'm currently working on to comply with the strategy pattern.
I need to process text using many string algorithms much like Lucene analyze and tokenize text. This is for an importation routine. Strategy:
public class ChainOfProcessor: IStringProcessor
{
public List<IStringProcessor> Processors;
public ChainOfProcessor()
{
Processors = new List<IStringProcessor>();
}
public ChainOfProcessor Add<TProcessor>()
where TProcessor: IStringProcessor, new()
{
return Add(new TProcessor());
}
public ChainOfProcessor Add(IStringProcessor processor)
{
Processors.Add(processor);
return this;
}
public string Process(string input)
{
return Processors.Aggregate(input, (current, processor) => processor.Process(current));
}
}
public interface IStringProcessor
{
string Process(string input);
}
public class HtmlStripper: IStringProcessor
{
public virtual string Process(string input)
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(input);
return htmlDoc.DocumentNode.InnerText;
}
}
public class HtmlDecoder: IStringProcessor
{
public string Process(string input)
{
return HttpUtility.HtmlDecode(input);
}
}
In Design Patterns, the authors use a Composition
class and Compositor
classes as examples. The client is allowed to chose a single Compositor
through Composition
to do whatever the Compositor
is supposed to do. There is a subtle difference in how the client uses the Composition
in my example. Instead of allowing a single IStringProcessor
to be used through some Composition
class, I allow many, to be executed one after the other through the concrete class ChainOfProcessor
. Usage:
var text = new ChainOfProcessor()
.Add<HtmlStripper>()
.Add<HtmlDecoder>()
.Process(html);