Factory Pattern vs Abstract Factory – What Is the Difference Between the Factory Pattern and Abstract Factory?

design-patternsfactory-method

Having finally begun seriously trying to learn some basic patterns (very late in the career, but that's a different story), I'm trying to get my head around the differences between the Factory Pattern and Abstract Factory.

What are the key differences between these two patterns?

I understand that the Factory Method creates objects through inheritance and Abstract Factory does it through object composition, but from a practical point of view, I'm still having trouble visualising exactly how they each work.

Best Answer

The Factory Method is usually categorised by a switch statement where each case returns a different class, using the same root interface so that the calling code never needs to make decisions about the implementation.

Think of a credit card validator factory which returns a different validator for each card type.

public ICardValidator GetCardValidator (string cardType)
{
    switch (cardType.ToLower())
    {
        case "visa":
            return new VisaCardValidator();
        case "mastercard":
        case "ecmc":
            return new MastercardValidator();
        default:
            throw new CreditCardTypeException("Do not recognise this type");
    }
}

The Abstract Factory is where you have multiple concrete factory classes (not Factory Methods) derived from one interface which may return many different types from different methods.

Think of a chess game manager with a different class for each set of variant rules.

public class StandardChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class HexagonalChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new HexagonalChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new HexagonalChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class SpeedChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new SpeedChessMoveClock();
    }
}

An Abstract Factory, much like a Strategy, is often selected using a Factory Method, but it isn't necessary to combine them so it is its own pattern.