Factory Method
Factory Method is a creational pattern. It is the only pattern classified as a creational class pattern. A creational class pattern is a pattern that uses inheritance to vary the objects created. Other creational patterns are creational object patterns. Those patterns delegate the creation of objects to other objects.
Quick Reference
Pattern Name | Factory Method |
Other Names | Virtual Constructor |
Classification | Class Creational |
Intent | Defines a standard interface for object creation, Defers instantiation to subclass |
General Structure
From the above diagram, the abstract creator has an interface that will create and return an abstract product. The actual products that will be created are derived from this abstract product.
The factory method is a pure virtual function in this base creator class with a return type of abstract product (thus allowing any concrete product derived from it to be returned)
It is up to the concrete creators to determine what the factory method will actually return.
Example
The following diagram is constructed using the same positions as the general uml diagram. In this example, we have factory method makePlayer. In the operation createPlayer(), it calls makePlayer() which is implemented in each of the concrete GoFishGame and PokerGame classes.
#include <iostream>
#include <string>
using namespace std;
class Player{
string playerType_;
public:
Player(string s){
playerType_=s;
}
void print(){
cout << playerType_ << endl;
}
};
class PokerPlayer:public Player{
public:
PokerPlayer():Player("poker player"){}
};
class GoFishPlayer:public Player{
public:
GoFishPlayer():Player("Go Fish Player"){}
};
class CardGame{
protected:
int numPlayers_;
Player* players_[10];
bool playerInit_;
public:
CardGame(int numplayers){
numPlayers_=numplayers;
playerInit_=false;
}
void createPlayers(){
for(int i=0;i<numPlayers_;i++){
players_[i]=makePlayers();
}
}
//makePlayers is our factory method
//the type of players that we make are
//dependent on the the type of game this
//is
virtual Player* makePlayers()=0;
void print(){
if(!playerInit_){
createPlayers();
playerInit_=true;
}
for(int i=0;i<numPlayers_;i++){
players_[i]->print();
}
}
};
class PokerGame:public CardGame{
public:
PokerGame():CardGame(5){
}
virtual Player* makePlayers(){
return new PokerPlayer();
}
};
class GoFishGame:public CardGame{
public:
GoFishGame():CardGame(4){
}
virtual Player* makePlayers(){
return new GoFishPlayer();
}
};
int main(void){
CardGame* p = new PokerGame();
CardGame* g = new GoFishGame();
cout << ".........Poker........"<< endl;
p->print();
cout << endl;
cout << ".........Go Fish......" << endl;
g->print();
return 0;
}