The abstract factory is a software design pattern used to create different family objects. The important thing here is that those classes must be related, in order to be used with an abstract class.
My example consist of 2 classes, named Circle and Rectangle. This 2 classes have something in common, they’re geometric figures and for example, both have an area formula.
I have seen a couple of examples in which the author just set the abstract class for the concrete classes. With this approach we will need to create an instance of the class based on the abstract class.
E.g. GeometricFigureAbstractClass obj = new Circle() (In this case, circle inherits from GeometricFigureAbstractClass, see example below).
I think this is not good enough, if all the classes contains in some way related methods why not just create a concrete and general class that will handle all of this behavior.
Now, first of all create the abstract class named GeometricFigure:
/// <summary>
/// Base class for all the geometric figures.
/// </summary>
abstract class GeometricFigure
{
public abstract string AreaFormula();
}
Now the concrete classes for that will inherit from GeometricFigure, in this case Circle and Rectangle.
/// <summary>
/// Circle concrete class, who inherits from GeometricFigures
/// </summary>
sealed class Circle : GeometricFigure
{
public override string AreaFormula()
{
return “pi * radius ^ 2″;
}
}
/// <summary>
/// Rectangle concrete class, who inherits from GeometricFigures
/// </summary>
sealed class Rectangle : GeometricFigure
{
public override string AreaFormula()
{
return “length * width”;
}
}
Now it’s time to create the factory, the class that will be in charge of creating the expected class from our request, using the enumerator we just created above.
/// <summary>
/// Class that creates an instance of a class that inherits from GeometricFigure
/// </summary>
sealed class GeometricFigureFactory
{
/// <summary>
/// Returns the concrete class instance that inherits from GeometricFigure
/// </summary>
/// <param name=”type”>The type of the concrete class to instantiate</param>
/// <returns></returns>
public GeometricFigure ReturnGeometricFigure(GeometricFigureType type)
{
GeometricFigure figure;
switch (type)
{
case GeometricFigureType.Circle:
figure = new Circle();
break;
default:
figure = new Rectangle();
break;
}
return figure;
}
}
This class contains a simple method called ReturnGeometricFigure that expects an enumeration type. This enum type will be the key in order to create the instance we requested, for example, if we need to create an instance of the class Circle just send the Circle enum type. It will return an instance of Circle, that inherits from GeometricFigure.
This is enough as an abstract factory, but we can go further.
Lets create a Manager, a class that will be used to get the information from the every single class of factory using one instance, my manager instance.
/// <summary>
/// Manager class that simplifies the abstract factory use. Can use all the classes that inherits from GeometricFigure
/// using the Factory class.
/// </summary>
sealed class GeometricFigureManager
{
public string GetAreaFormula(GeometricFigureType Type)
{
GeometricFigureFactory factory = new GeometricFigureFactory();
GeometricFigure figure = factory.ReturnGeometricFigure(Type);
return figure.AreaFormula();
}
}
As I said before, the Circle and the Rectangle both contains an area right?. What if I want to get the formula of the circle and the rectangle? we will need to create both instances, but with this manager we can have both. The Manager receives the GeometricFigureType, the manager creates the instance using the factory and will send the formula from the instantiated class.
In fact, we can use a Singleton pattern in order to have only one instance of the Manager in the whole application
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AbstractFactorySample
{
class Program
{
static void Main(string[] args)
{
//Regular abstract method way
//Create a circle instance, get area
GeometricFigure circle = new Circle();
string circleFormula = circle.AreaFormula();
//Create a rectangle instance, get area
GeometricFigure rect = new Rectangle();
string rectFormula = rect.AreaFormula();
//All this can be reduced to a single object
GeometricFigureManager manager = new GeometricFigureManager();
var formulaRect = manager.GetAreaFormula(GeometricFigureType.Rectangle);
var formulaCirc = manager.GetAreaFormula(GeometricFigureType.Circle);
}
}
/// <summary>
/// Base class for all the geometric figures.
/// </summary>
abstract class GeometricFigure
{
public abstract string AreaFormula();
}
/// <summary>
/// Circle concrete class, who inherits from GeometricFigures
/// </summary>
sealed class Circle : GeometricFigure
{
public override string AreaFormula()
{
return “pi * radius ^ 2″;
}
}
/// <summary>
/// Rectangle concrete class, who inherits from GeometricFigures
/// </summary>
sealed class Rectangle : GeometricFigure
{
public override string AreaFormula()
{
return “length * width”;
}
}
/// <summary>
/// Class that creates an instance of a class that inherits from GeometricFigure
/// </summary>
sealed class GeometricFigureFactory
{
/// <summary>
/// Returns the concrete class instance that inherits from GeometricFigure
/// </summary>
/// <param name=”type”>The type of the concrete class to instantiate</param>
/// <returns></returns>
public GeometricFigure ReturnGeometricFigure(GeometricFigureType type)
{
GeometricFigure figure;
switch (type)
{
case GeometricFigureType.Circle:
figure = new Circle();
break;
default:
figure = new Rectangle();
break;
}
return figure;
}
}
/// <summary>
/// Manager class that simplifies the abstract factory use. Can use all the classes that inherits from GeometricFigure
/// using the Factory class.
/// </summary>
sealed class GeometricFigureManager
{
public string GetAreaFormula(GeometricFigureType Type)
{
GeometricFigureFactory factory = new GeometricFigureFactory();
GeometricFigure figure = factory.ReturnGeometricFigure(Type);
return figure.AreaFormula();
}
}
/// <summary>
/// The classes that inherits from GeometricFigure
/// </summary>
public enum GeometricFigureType
{
Circle,
Rectangle
}
}





