Abstract Factory Pattern

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 factory also uses another another set of concrete types (specific to itself) based on an abstract class.

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");
    	}
    }
}
Last updated on 02 February 2009

Comments

blog comments powered by Disqus