Use a Dictionary<Char, YourDelegate>
to specify how a character should be handled. Call DefaultHandler
if the character key do not exist in the dictionary.
Add a Add(char key, YourDelegate handler)
method allowing anyone to handle a specific character.
Update
It's better to work with interfaces:
/// <summary>
/// Let anyone implement this interface.
/// </summary>
public interface IMyHandler
{
void Process(IProcessContext context, string line);
}
/// <summary>
/// Context information
/// </summary>
public interface IProcessContext
{
}
// Actual parser
public class Parser
{
private Dictionary<char, IMyHandler> _handlers = new Dictionary<char, IMyHandler>();
private IMyHandler _defaultHandler;
public void Add(char controlCharacter, IMyHandler handler)
{
_handlers.Add(controlCharacter, handler);
}
private void Parse(TextReader reader)
{
StringBuilder scope = new StringBuilder();
IProcessContext context = null; // create your context here.
string line = reader.ReadLine();
while (line != null)
{
IMyHandler handler = null;
if (!_handlers.TryGetValue(line[0], out handler))
handler = _defaultHandler;
handler.Process(context, line);
line = reader.ReadLine();
}
}
}
Note that I pass in a TextReader
instead. It gives much more flexibility since the source can be anything from a simple string to a complex stream.
Update 2
I would also break up the !
handling in a similar way. i.e. Create a class that handles IMyHandler:
public interface ICommandHandler
{
void Handle(ICommandContext context, string commandName, string[] arguments);
}
public class CommandService : IMyHandler
{
public void Add(string commandName, ICommandHandler handler)
{
}
public void Handle(IProcessContext context, string line)
{
// first word on the line is the command, all other words are arguments.
// split the string properly
// then find the corrext command handler and invoke it.
// take the result and add it to the `IProcessContext`
}
}
That gives more flexibility for both handling the actual protocol and add more commands. you do not have to change anything to add more functionality. The solution is therefore OK regarding Open/Closed and some other SOLID principles.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…