.net - ejercicios - ¿Cuáles son las diferencias entre los patrones Builder, Factory Method y Abstract Factory?
patron de diseño abstract factory c# ejemplo (2)
Un programa recibe una lista de mensajes (tipo de base). Cada mensaje en la lista debe ser procesado de acuerdo a su tipo (tipo de descendiente). Sin embargo, diferentes mensajes necesitan diferentes entradas para ser procesados correctamente.
¿Cómo se llama la siguiente técnica? (No he comprobado este código en un compilador)
abstract class MessageProcessor
{
public static MessageProcessor GetProcessor(Message message, DataDomain data)
{
if (message.GetType() == typeof(FooMessage))
{
return new FooMessageProcessor(message, data.Name, data.Classification);
}
else if (message.GetType() == typeof(BarMessage))
{
return new BarMessageProcessor(message, data.AccountNo, data.CreditLimit);
}
else
throw new SomeException("Unrecognized type");
}
public abstract void Process();
}
¿Y éste?
static class MessageProcessorFactory
{
public static MessageProcessor GetProcessor(Message message, DataDomain data)
{
if (message.GetType() == typeof(FooMessage))
{
return new FooMessageProcessor(message, data.Name, data.Classification);
}
else if (message.GetType() == typeof(BarMessage))
{
return new BarMessageProcessor(message, data.AccountNo, data.CreditLimit);
}
else
throw new SomeException("Unrecognized type");
}
}
¿Y cómo se llama si puedo inyectar la clase ProcessBuilder en un MessageProcessor (usando una propiedad o Setter) y luego llamar a Process?
¿Qué técnica sería el mejor patrón para resolver este problema?
Ambos son ejemplos del patrón de método de fábrica . La única diferencia es que el segundo ejemplo tiene el método en su propia clase estática.
Este sería un ejemplo del patrón abstracto de fábrica :
abstract class MessageProcessorFactory
{ public abstract MessageProcessor GetProcessor
(Message message, DataDomain data);
}
class FooMessageProcessorFactory : MessageProcessorFactory
{ public override MessageProcessor GetProcessor
(Message message, DataDomain data)
{ return new FooMessageProcessor(data.Name, data.Classification);
}
}
Cada MessageProcessor obtiene su propia clase de fábrica que hace uso del polimorfismo.
Pasar un ProcessBuilder para crear el proceso sería el patrón de estrategia :
class MessageProcessor
{ ProcessBuilder builder;
public MessageProcessor(ProcessBuilder builder)
{ this.builder = builder;
}
public void Process()
{ builder.BuildMessage();
builder.BuildProcess();
builder.Process();
}
}
var mp = new MessageProcessor(new FooProcessBuilder());
La solución más simple sería encapsular un método de fábrica:
static void Process(Message msg, DataDomain data)
{ var p = getProcessor(msg.GetType());
p.Process(msg, data);
}
Si se trata de una pequeña cantidad conocida de tipos, puede usar la serie de comprobaciones de tipo:
private static MessageProcessor getProcessor(Type msgType)
{ return (msgType == typeof(FooMessage)) ? new FooMessageProcessor()
: (msgType == typeof(BarMessage)) ? new BarMessageProcessor()
: new DefaultMessageProcessor();
}
De lo contrario, use un diccionario:
Dictionary<Type,MessageProcessor> processors;
private static MessageProcessor getProcessor(Type msgType)
{ return processors[msgType];
}
En mi opinión , el método de la fábrica defnies el tipo abstracto de clase con el que trabajar, pero delega la creación del tipo concreto a las clases posteriores / implementadoras. La fábrica abstracta definiría una interfaz para un fabricante de un conjunto de clases correspondientes. Un constructor funciona simplemente para construir un objeto paso a paso, dando cierto control a la instancia de llamada.