Padrão de Design de fábrica abstrata

Estou trabalhando em um projeto interno para minha empresa e parte do projeto é capaz de analisar várias "Tarefas" de um arquivo XML em uma coleção de tarefas a serem executadas posteriormente.

Como cada tipo de tarefa possui vários campos associados diferentes, decidi que seria melhor representar cada tipo de tarefa com uma classe separada.

Para fazer isso, construí uma classe base abstrata:

public abstract class Task
{
    public enum TaskType
    {
        // Types of Tasks
    }   

    public abstract TaskType Type
    {
        get;
    }   

    public abstract LoadFromXml(XmlElement task);
    public abstract XmlElement CreateXml(XmlDocument currentDoc);
}

Cada tarefa herdada dessa classe base e incluiu o código necessário para se criar a partir do XmlElement passado, além de seriar novamente para um XmlElement.

Um exemplo básico:

public class MergeTask : Task
{

    public override TaskType Type
    {
        get { return TaskType.Merge; }
    }   

    // Lots of Properties / Methods for this Task

    public MergeTask (XmlElement elem)
    {
        this.LoadFromXml(elem);
    }

    public override LoadFromXml(XmlElement task)
    {
        // Populates this Task from the Xml.
    }

    public override XmlElement CreateXml(XmlDocument currentDoc)
    {
        // Serializes this class back to xml.
    }
}

O analisador usaria código semelhante a este para criar uma coleção de tarefas:

XmlNode taskNode = parent.SelectNode("tasks");

TaskFactory tf = new TaskFactory();

foreach (XmlNode task in taskNode.ChildNodes)
{
    // Since XmlComments etc will show up
    if (task is XmlElement)
    {
        tasks.Add(tf.CreateTask(task as XmlElement));
    }
}

Tudo isso funciona maravilhosamente e me permite passar tarefas usando a classe base, mantendo a estrutura de ter classes individuais para cada tarefa.

No entanto, não estou satisfeito com meu código para TaskFactory.CreateTask. Este método aceita um XmlElement e, em seguida, retorna uma instância da classe Task apropriada:

public Task CreateTask(XmlElement elem)
{
    if (elem != null)
    {
        switch(elem.Name)
        {
            case "merge":
                return new MergeTask(elem);
            default:
                throw new ArgumentException("Invalid Task");
        }
    }
}

Como tenho que analisar o XMLElement, estou usando uma grande (10 a 15 casos no código real) para escolher qual classe filho instanciar. Espero que exista algum tipo de truque polimórfico que eu possa fazer aqui para limpar esse método.

Algum conselho?

questionAnswers(0)

yourAnswerToTheQuestion