To be perfectly honest, it took me a while and a not unreasonable amount of swearing to get this up and running – but I guess that’s par for the course when you’re learning new things. Or at least that seems to be the case with me.

The Abstract Factory design pattern itself looks like this:

While the example code, involving continents, herbivores and carnivores goes like this:

// The 'AbstractFactory' abstract class. Pure abstract class - cannot be instantiated, but again we can create pointers to one.

classContinentFactory

{

public:

virtualHerbivore*CreateHerbivore()=0;

virtualCarnivore*CreateCarnivore()=0;

};

// The 'ConcreteFactory1' class

classAfricaFactory:publicContinentFactory

{

public:

virtualHerbivore*CreateHerbivore()

{

returnnewWildebeest("William Wildebeest");

}

virtualCarnivore*CreateCarnivore()

{

returnnewLion("Lenny Lion");

}

};

// The 'ConcreteFactory2' class

classAmericaFactory:publicContinentFactory

{

virtualHerbivore*CreateHerbivore()

{

returnnewBison("Bob Bison");

}

virtualCarnivore*CreateCarnivore()

{

returnnewWolf("Walter Wolf");

}

};

// The 'Client' class. This class calls the factory classes to create animals of the relevant type.

classAnimalWorld

{

private:

Herbivore*mHerbivore;

Carnivore*mCarnivore;

public:

// Constructor. Creates a suitable pair of herbivores and carnivores for the continent.

AnimalWorld(ContinentFactory*pFactory)

{

mHerbivore=pFactory->CreateHerbivore();

mCarnivore=pFactory->CreateCarnivore();

}

voidrunFoodChain()

{

mCarnivore->eat(*mHerbivore);

}

};

// Let the carnage begin...

intmain()

{

// Create and run the African animal world

ContinentFactory*pAfrica=newAfricaFactory;

AnimalWorld*pWorld=newAnimalWorld(pAfrica);

pWorld->runFoodChain();

// Create and run the American animal world

ContinentFactory*pAmerica=newAmericaFactory;

pWorld=newAnimalWorld(pAmerica);

pWorld->runFoodChain();

return0;

}

That’s a lot of work to get the output:

Shell

1

2

Lenny Lion eats William Wildebeest

Walter Wolf eats Bob Bison

But the point isn’t the output, it’s the structure of the classes and how it does what it does. Now I just have to learn when and how to apply the pattern to problems not involving imaginary animals… =D