Patrón de diseño abstracto de fábrica

Estoy trabajando en un proyecto interno para mi empresa, y parte del proyecto es poder analizar varias "Tareas" de un archivo XML en una colección de tareas que se ejecutarán más adelante.

Debido a que cada tipo de tarea tiene una multitud de diferentes campos asociados, decidí que sería mejor representar cada tipo de tarea con una clase separada.

Para hacer esto, construí una clase base abstracta:

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 tarea heredó de esta clase base e incluyó el código necesario para crearse a sí mismo a partir del pasado en XmlElement, así como también volver a serializarse en un XmlElement.

Un ejemplo 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.
    }
}

El analizador usaría un código similar a este para crear una colección de tareas:

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));
    }
}

Todo esto funciona de maravilla y me permite pasar tareas utilizando la clase base, al tiempo que conserva la estructura de tener clases individuales para cada tarea.

Sin embargo, no estoy satisfecho con mi código para TaskFactory.CreateTask. Este método acepta un XmlElement y luego devuelve una instancia de la clase de tarea adecuada:

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

Debido a que tengo que analizar el XMLElement, estoy usando un interruptor enorme (10-15 casos en el código real) para elegir qué clase secundaria crear. Espero que haya algún tipo de truco polimórfico que pueda hacer aquí para limpiar este método.

¿Algún consejo?

Respuestas a la pregunta(0)

Su respuesta a la pregunta