BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Abstract Factory Design Pattern

The abstract factory pattern is a design pattern that allows for the creation of groups of related objects without the requirement of specifying the exact concrete classes that will be used. One of a number of factory classes generates the object sets.

What is the Abstract Factory Pattern?

The abstract factory pattern is a Gang of Four design pattern. This is a creational pattern, as it is used to control class instantiation. The abstract factory pattern is used to provide a client with a set of related or dependant objects. The "family" of objects created by the factory is determined at run-time according to the selection of concrete factory class.

As an example, consider a program that assists with the packaging and delivery of items for a web-based store. The company delivers two types of product. The first is a standard product that is placed in a box and delivered through the post with a simple label. The second is a delicate item that requires shockproof packaging and is delivered via a courier that requires a detailed manifest.

In this situation, there are two types of object required, a packaging object and a delivery documentation object. We could use two factories to generate these related objects. The StandardPurchaseFactory may produce StandardPackaging and PostalLabel objects whilst the DelicatePurchaseFactory creates ShockProofPackaging and CourierManifest objects.

Implementing the Abstract Factory Pattern

Abstract Factory Design Pattern UML

The UML class diagram above describes an implementation of the abstract factory design pattern. The classes in the diagram are described below:

  • Client. This class uses the factories to generate a family of related objects. In the UML diagram, the client has two private fields that hold instances of the abstract product classes. The underlying objects will be related to each other but the actual types can remain unknown, as they will only be accessed via their base class interfaces. When a client is instantiated, a concrete factory object is passed to the constructor and used to populate the private fields.
  • AbstractFactory. This is an abstract base class for the concrete factory classes that will generate new sets of related objects. A method is included for each type of object that will be instantiated. This class could be replaced with a simple interface. However, generally an abstract class will be used so that other standard functionality can be included and inherited by all of the concrete factory subclasses.
  • ConcreteFactory (A/B). Inheriting from the AbstractFactory class, the concrete factory classes override the methods that generate the suite of objects required by the client. There may be any number of concrete factories depending upon the requirements of the software.
  • AbstractProduct (A/B). This abstract class is the base class for the types of object that a factory can create. One base type exists for each of the distinct types of product required by the client.
  • ConcreteProduct (A/B). Multiple subclasses of the ConcreteProduct classes are defined, each containing specific functionality. Objects of these classes are generated by the abstract factory to populate the client.

The following code shows the basic code of the abstract factory design pattern implemented using C#:

public class Client
{
    private AbstractProductA _productA;
    private AbstractProductB _productB;

    public Client(AbstractFactory factory)
    {
        _productA = factory.CreateProductA();
        _productB = factory.CreateProductB();
    }
}


public abstract class AbstractFactory
{
    public abstract AbstractProductA CreateProductA();

    public abstract AbstractProductB CreateProductB();
}


public class ConcreteFactoryA : AbstractFactory
{
    public override AbstractProductA CreateProductA()
    {
        return new ProductA1();
    }

    public override AbstractProductB CreateProductB()
    {
        return new ProductB1();
    }
}


public class ConcreteFactoryB : AbstractFactory
{
    public override AbstractProductA CreateProductA()
    {
        return new ProductA2();
    }

    public override AbstractProductB CreateProductB()
    {
        return new ProductB2();
    }
}


public abstract class AbstractProductA { }

public class ProductA1 : AbstractProductA { }

public class ProductA2 : AbstractProductA { }

public abstract class AbstractProductB { }

public class ProductB1 : AbstractProductB { }

public class ProductB2 : AbstractProductB { }
4 August 2008