Saturday, September 23, 2006

Simple factory pattern usando diccionarios de metodos en C#

He estado hablando de arreglos de metodos, diccionarios de metodos, como ambas tecnicas son muy similares en la implementacion, cuando puedes usar una u otra y un ejemplo practico del patron de creacion simple usando arreglos de metodos. Hoy les mostrare la implementacion de este patron usando diccionarios de metodos y luego ya blogueare sobre cosas mas interesantes, Steven posteo una implementacion de este mismo paterno, pero mucho mas elegante usando tipos genericos y generacion dinamica de codigo usando ILGenerator, aun asi pongo el codigo aqui para dejar un ejemplo mas de como usar los diccionarios de metodos.

using ReportCreatorDictionary = Dictionary<string, ReportCreatorDelegate>;
//Este es nuestro producto base
abstract class BaseReport {
public BaseReport() {
Console.WriteLine("Base Report Created");
}
public abstract void Execute();
}
//producto 1
class Report1 : BaseReport {
public Report1():base() {
Console.WriteLine("Report1 created");
}
public override void Execute() {
Console.WriteLine("Report1");
}
}
//producto 2
class Report2 : BaseReport {
public Report2():base() {
Console.WriteLine("Report2 created");
}
public override void Execute() {
Console.WriteLine("Report2");
}
}

delegate BaseReport ReportCreatorDelegate();
//esta es la fabrica
class ReportGenerator {

static BaseReport CreateReport1() {
return new Report1();
}

static BaseReport CreateReport2() {
return new Report2();
}

static ReportCreatorDictionary reports;

static ReportGenerator() {
reports = new ReportCreatorDictionary();
reports.Add("Report1", new ReportCreatorDelegate(CreateReport1));
reports.Add("Report2", new ReportCreatorDelegate(CreateReport2));
}

public static BaseReport Execute(string reportType) {
return reports[reportType]();
}
}

y la forma de usarlo:

BaseReport report1 = ReportGenerator.Execute("Report1");
report1.Execute();

BaseReport report2 = ReportGenerator.Execute("Report2");
report2.Execute();

Por supuesto que la opcion del reporte que queremos ejecutar puede venir de donde sea (un drop down list, un link en una pagina web, configuracion, etc)


El problema con esta implementacion, como lo menciona Steven, es que tienes que cambiar la fabrica cada que agregas un producto nuevo, y no es flexible como para permitir un modelo de plug-in, porque todos los tipos se necesitan conocer al tiempo de compilar; y si necesitas una fabrica para crear otra serie de productos tienes que escribir una nueva fabrica (pues claro!!... podria pensar uno). Pues resulta que con la implementacion de Steven ya no necesitas escribir una fabrica nueva, sino que el escribio una fabrica generica que puedes reusar con cualquier producto, solo le agregas los productos, internamente esta crea los metodos necesarios para crear la instancia del producto que agregaste, y esta lista para usarse, realmente esta muy interesante, te recomiendo que la leas (aunque solo esta en ingles =o( )


El codigo de Steven me ha dado otra idea, tendre que ver si funciona asi como me lo imagino y luego ya posteare sobre el tema


Por ahora, aqui esta el codigo completo para los diccionarios de metodos y este ejemplo de la fabrica; como siempre, juega con el codigo, muevele, quiebralo, mejoralo

No comments: