Factory Pattern
Define
an interface for creating an object, but let subclasses decide which class to
instantiate. Factory Method lets a class defer instantiation to subclasses.
Application
Use the Factory Method pattern when
· a class can't anticipate the class of objects it must create.
· a class
wants its subclasses to specify the objects it creates.
· classes
delegate responsibility to one of several helper subclasses, and you want to
localize the knowledge of which helper subclass is the delegate.
Implementation
1.
Two major varieties. The two main variations of the
Factory Method pattern are (1) the case when the Creator class
is an abstract class and does not provide an implementation for the
factory method it declares, and (2) the case when the Creator is a concrete class and provides a
default implementation for the factory method.
2.
Parameterized
factory methods. Another variation on the pattern lets
the factory method create multiple kinds of products. The factory method takes a parameter that identifies the kind of object to create.
class
Creator {
public:
virtual
Product* Create(ProductId);
};
Product*
Creator::Create (ProductId id) { //
initialization based on its parameters
if (id ==
MINE) return new MyProduct;
if (id ==
YOURS) return new YourProduct;
//
repeat for remaining products...
return 0;
}
3.
Using
templates to avoid subclassing.
The potential problem
with factory methods is that they might force you to subclass just to create
the appropriate Product objects. In C++ can be solved with template.
class
Creator
{
public:
virtual Product*
CreateProduct() = 0; //pure virtual method
};
template <class TheProduct>
class
StandardCreator:
public Creator {
public:
virtual
Product* CreateProduct();
};
template <class TheProduct>
Product*
StandardCreator<TheProduct>::CreateProduct
() {
return new TheProduct;
}
Sample
Code
The Default MazeGame creator
class MazeGame {
public:
Maze*
CreateMaze(); //template
method, which responsible to create object
//
factory methods:
virtual Maze*
MakeMaze() const
{ return new Maze; }
virtual Room*
MakeRoom(int n) const
{ return new Room(n); }
virtual Wall*
MakeWall() const
{ return new Wall; }
virtual Door*
MakeDoor(Room* r1, Room* r2) const
{ return new Door(r1, r2); }
};
class EnchantedMazeGame : public MazeGame { // subclassing
based on specific required
public:
EnchantedMazeGame();
virtual
Room* MakeRoom(int n) const // override factory method based on requirements
{ return new EnchantedRoom(n,
CastSpell()); }
virtual
Door* MakeDoor(Room* r1, Room* r2) const
{ return new DoorNeedingSpell(r1, r2);
}
protected:
Spell*
CastSpell() const;
};
Comments
Post a Comment