Factory Pattern

When we are designing systems we can make use of a variety of deign patterns. They are valuable for many reasons, not least that using a common and understood way of designing something means that it will be easily understood by people familiar with the pattern.

The Factory Design pattern can be used when you have a large number of similar objects (so can be referred to through a common interface or abstract class), and where you wish to hide the instantiation logic from the calling class.

Consider a simple drawing program. You might want to create one of a large number of types of shape, square, circle, triangle etc.

We can use a Factory class to return an instance of the type of shape we want:


public abstract class Shape
{
  public abstract Shape createShape();
}

public class Square : Shape
{
  public Square() {}

  public override Shape createShape()
  {
    return new Square();
  }
}

public class ShapeFactory
{
  Dictionary<string, Shape> registeredShapes;

  private static readonly ShapeFactory instance = new ShapeFactory();

  private ShapeFactory()
  {
    registeredShapes = new Dictionary<string, Shape>();
    var Shapes = from b in Assembly.GetExecutingAssembly().GetTypes()
                 where b.IsSubclassOf(typeof(Shape))
                 select b;

    foreach (var type in Shapes)
    {
      var s = type.GetConstructor(System.Type.EmptyTypes).Invoke(null);
      registeredShapes.Add(type.Name, (Shape)s);
    }
  }

  public static ShapeFactory Instance
  {
    get
    {
       return instance;
    }
  }

  public Shape createShape(string shapeName)
  {
    return ((Shape)registeredShapes[shapeName]).createShape();
  }
}

From this we can simply call ShapeFactory.Instance.createShape(“Square”); and this will give us a new instance of the Square object.

As we expand to define extra types of shape, we won’t need to alter the Factory, we can just implement the new shape, it will be discovered automatically, thanks to the use of reflection.

Whilst this is clearly a simple example, where we are just creating and return the objects, it should be easy to see that we can use much more complicated objects. We would hide all the creation logic inside each type, and use the factory to pass an fully created concrete instance whenever one is required.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s