Chris's coding blog

C# Design Patterns: the Abstract Factory Pattern

January 02, 2009

Summary

The abstract factory is the base class of all factory classes, but is responsible for creating instances of the classes that are derived from it (via a static method).

It goes one step further after this, so each derived class creates an instance of another abstract class (Renderer in my example) specialized for its use.

Example usage

As the code below illustrates, a common use is for abstracting GUI elements out, so that that each different concrete factory creates components for a different platform, this could be an operating system or device like the web/windows. This is a fairly common example that’s found in the Oreilly C# book and on wikipedia.

namespace DesignPatterns
{
public abstract class AbstractPluginFactory
{
public static AbstractPluginFactory GetFactory(string renderer)
{
switch (renderer)
{
case "ASPX":
return new ASPXRendererFactory();
case "Winforms":
return new WinformsRendererFactory();
default:
throw new NotSupportedException(string.Format("{0} is not supported", renderer));
}
}
public abstract Renderer Renderer { get; }
}
public class ASPXRendererFactory : AbstractPluginFactory
{
private Renderer _renderer;
public override Renderer Renderer
{
get
{
return _renderer;
}
}
public ASPXRendererFactory()
{
// This could be a protected field in PluginFactory
_renderer = new ASPXRenderer();
}
}
public class WinformsRendererFactory : AbstractPluginFactory
{
private Renderer _renderer;
public override Renderer Renderer
{
get
{
return _renderer;
}
}
public WinformsRendererFactory()
{
// This could be a protected field in PluginFactory
_renderer = new WinformsRenderer();
}
}
public abstract class Renderer
{
public abstract void DrawImage(string filename);
}
public class WinformsRenderer : Renderer
{
public override void DrawImage(string filename)
{
// This would draw onto a canvas provided via
// a Graphics object.
Console.WriteLine("Drawing an image for Windows forms");
}
}
public class ASPXRenderer : Renderer
{
public override void DrawImage(string filename)
{
// This would output an <img..> tag to the child controls or similar.
Console.WriteLine("Drawing an image for ASP.NET");
}
}
}
view raw gistfile1.cs hosted with ❤ by GitHub

csharpdesign-patterns

I'm Chris Small, a software engineer working in London. This is my tech blog. Find out more about me via GithubStackoverflowResume