C++ example for Abstract Factory Design Pattern

The Abstract Factory Design Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. The following UML class diagram explains how the Abstract Factory fits with the rest.


The following is example of Abstract factory design pattern:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Abstract Factory is part of Creational Patterns
//Creational Patterns deal with initializing and configuring classes and objects
//Abstract Factory creates an instance of several families of classes

//We will take an example of Animal Classes and Abstract them.
//There are 2 types of animals; Herbivores and Carnivores.
//The rule of nature is that Carnivores eats Herbivores which will be shown
//Different animas live in different continents but the same rule applies

#include<iostream>
#include<string>

using namespace
std;

//The Herbivore class - The 'AbstractProductA' abstract class
class Herbivore
{

public
:
virtual const
string& getName(void)=0;
};


//Lets define couple of Herbivores called Cow and Deer
class Cow : public Herbivore //The 'ProductA1' class
{
public
:
Cow():name("Cow"){};
//default destructor
const string& getName(void) {return name;}
private
:
string name;
};


class
Deer : public Herbivore //The 'ProductA2' class
{
public
:
Deer():name("Deer"){};
//default destructor
const string& getName(void) {return name;}
private
:
string name;
};


//The Carnivore class - The 'AbstractProductB' abstract class
class Carnivore
{

public
:
virtual const
string& getName(void)=0;
virtual
void eat(Herbivore& h) = 0;
};


//Lets define couple of Carnivores called Lion and Wolf
class Lion : public Carnivore //The 'ProductB1' class
{
public
:
Lion():name("Lion"){};
const
string& getName(void) {return name;}
void
eat(Herbivore& h) //override
{
cout << name << " eats " << h.getName() << endl;
}

private
:
string name;
};


class
Wolf : public Carnivore //The 'ProductB2' class
{
public
:
Wolf():name("Wolf"){};
const
string& getName(void) {return name;}
void
eat(Herbivore& h) //override
{
cout << name << " eats " << h.getName() << endl;
}

private
:
string name;
};


//The 'AbstractFactory' abstract class
class ContinentFactory
{

public
:
virtual
Herbivore& CreateHerbivore() = 0;
virtual
Carnivore& CreateCarnivore() = 0;
};


class
AfricaFactory : public ContinentFactory //The 'ConcreteFactory1' class
{
Herbivore& CreateHerbivore()
{

return
*(dynamic_cast<Herbivore *>(new Cow()));
}

Carnivore& CreateCarnivore()
{

return
*(dynamic_cast<Carnivore *>(new Lion()));
}
};


class
AmericaFactory : public ContinentFactory //The 'ConcreteFactory2' class
{
Herbivore& CreateHerbivore()
{

return
*(dynamic_cast<Herbivore *>(new Deer()));
}

Carnivore& CreateCarnivore()
{

return
*(dynamic_cast<Carnivore *>(new Wolf()));
}
};


//The 'Client' class
class AnimalWorld
{

public
:
AnimalWorld(ContinentFactory& factory):_herbivore(factory.CreateHerbivore()),_carnivore(factory.CreateCarnivore())
{
}

void
RunFoodChain()
{

_carnivore.eat(_herbivore);
}

private
:
Herbivore& _herbivore;
Carnivore& _carnivore;
};


int
main()
{

//Create and run African Animal World
ContinentFactory& africa = *(dynamic_cast<ContinentFactory *>(new AfricaFactory()));
AnimalWorld& world1 = *(new AnimalWorld(africa));
world1.RunFoodChain();

// Create and run the American animal world
ContinentFactory& america = *(dynamic_cast<ContinentFactory *>(new AmericaFactory()));
AnimalWorld& world2 = *(new AnimalWorld(america));
world2.RunFoodChain();

return
0;
}





The output is as follows:



For more details please see: http://www.dofactory.com/Patterns/PatternAbstract.aspx

Check out this stream