Saturday, September 23, 2006

Simple factory pattern using Dictionaries of methods

I have been talking about arrays of methods, dictionaries of methods, how both techniques are very similar in implementation, when you can use either one, and a practical implementation of the simple factory pattern using arrays of methods. Today I'll show you the implementation of the simple factory pattern using dictionaries of methods and then we'll move into more interesting things, Steven posted an implementation of the same pattern that leaves my implementation in the dust, I'm still posting my code here as another example of how you can use dictionaries of methods. 

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

delegate BaseReport ReportCreatorDelegate();
//this is the actual factory
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]();
}
}

and the way to use it:

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

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

of course the choice of the report to be executed can come from anywhere (drop down list, link on a web page, configuration, etc)


The problem with this implementation, as Steven points out, is that you have to change the factory every time you add a new product to the factory and is not flexible enough to create (for example) a plug-in model, because all the types are required to be known at compile time; and if you need a factory for another product you have write a new factory (duh!, you might think). Steve's implementation is a Generic factory that can be re-used with any other types (products); no need to write the factory, you just add the products to it and is ready to be used, go check it out, is definitely worth reading.


Steve's code has given me another idea, I'll see if it actually works the way I have pictured it and then blog about it


for now here's the code for the dictionaries of methods and this example of the factory; as always, play with it, learn from it, improve it


kick it on DotNetKicks.com

1 comment:

Miguel said...

Hi very didactic example. Thx!
Do you have Steven´s implementation source code....?