Pages

Tuesday, March 6, 2012

Abstract Factory Design Pattern

An abstract factory provides an interface for creating families of related objects without specifying their concrete classes. Sometimes one wants to construct an instance of one of a suite of classes, deciding between the classes at the time of instantiation. In order to avoid duplicating the decision making everywhere an instance is created, we need a mechanism for creating instances of related classes without necessarily knowing which will be instantiated. Abstract Factory is an abstract class defining a common protocol of Factory methods. Concrete subclasses of the abstract factory implement this protocol to answer instances of the appropriate suite of classes. This is useful when there is a need to have multiple families of products. The system shall be configured with one of multiple families of products.

Here is an example. Suppose there is a computer factory which needs to create CPU and Memory as products. An interface ComputerFactory is defined which defines the abstract methods for creating abstract CPU and Memory. A concrete computer factory is defined by the class ComputerFactoryA which creates the suit of products belonging to the ‘A’ series i.e. CPUA and MemoryA. Note that CPUA and MemoryA implement the respective interfaces CPU and Memory which represents the abstract products. There is a test class called Client which defines a static method to create the suit of products. Note that this method is a like a template which is independent of the particular suit of products. We just need to pass the object of a concrete factory of our interest and it will create the related products.


//The Abstract ComputerFactory to create an Abstract CPU and Memory
public interface ComputerFactory
{
    CPU createCPU();
    Memory createMemory();
}

//Abstract CPU
public interface CPU
{
    string GetCPU();
}

//Abstract Memory
public interface Memory
{
    string GetMemory();
}

//Concrete ComputerFactoryA tp create CPUA and MemoryA
public class ComputerFactoryA : ComputerFactory
{
    public CPU createCPU() { return new CPUA(); }
    public Memory createMemory() { return new MemoryA(); }
}

//Concrete CPUA
public class CPUA : CPU
{
    public string GetCPU() { return "CPUA"; }
}

//Concrete MemoryA
public class MemoryA : Memory
{
    public string GetMemory() { return "MemoryA"; }
}

//client class
using System;
public class Client
{
    //this is a template method; does not depend on the Concrete Factory 
    //and the Concrete classes
    public static void BuildComputer(ComputerFactory factory)
    {
        CPU cpu = factory.createCPU();
        Memory memory = factory.createMemory();
        Console.WriteLine("CPU:{0}", cpu.GetCPU());
        Console.WriteLine("Memory:{0}", memory.GetMemory());
    }    
}

This how the test code would look like:

Client.BuildComputer(new ComputerFactoryA());

No comments: