适用性:
1当一个类不知道它所必须创建的对象的类的时候
2当一个类希望它的子类来指定所创建对象的时候
3当类将创建对象的职责委托给多个帮助子类中的一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
效果:
1不再将与特定应用有关的类邦定到代码中。
2为子类提供挂钩(hook) 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。Factory Method给子类一个挂钩以提供对象的扩展版本
3连接平行的类层次
实现:
1两种不同情况 1)Creator是抽象类并且不提供它所声明的工厂方法的实现
2)Creator是一个具体的类而且为工厂方法提供一个缺省的实现
2 参数化工厂方法 工厂方法采用一个标识要被创建的对象种类的参数
3C++中的工厂方法都是虚函数并且常常是纯虚函数
4使用模板以避免创建子类
抽象工厂与工厂方法的区别:
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
示例代码如下:
Factory.h
- #include <string>
- #define MAX_ROOM_NO 30
- enum Direction {North,South,East,West,Length};
- class Mapsite
- {
- public:
- Mapsite(){}
- virtual ~Mapsite(){}
- virtual void Enter() = 0;
- };
- class Room : public Mapsite
- {
- public:
- Room(int roomNo);
- int GetRoomNo(){return roomNumber;}
- Mapsite* GetSide(Direction) const;
- void SetSide(Direction,Mapsite*);
- virtual void Enter();
- private:
- Mapsite* _sides[4];
- int roomNumber;
- };
- class EnchantedRoom:public Room
- {
- public:
- EnchantedRoom(int roomNo);
- };
- class Wall:public Mapsite
- {
- public:
- Wall();
- virtual void Enter();
- };
- class Door:public Mapsite
- {
- public:
- Door(Room* = 0,Room* = 0);
- virtual void Enter();
- Room * OtherSideFrom(Room*);
- private:
- Room* _room1;
- Room* _room2;
- bool _isOpen;
- };
- class EnchantedDoor:public Door
- {
- public:
- EnchantedDoor(Room* = 0,Room* = 0);
- };
- class Maze {
- public:
- //Maze();
- void AddRoom(Room *);
- Room* RoomNo(int) const;
- private:
- Room *a[MAX_ROOM_NO];
- };
- class MazeGame
- {
- public:
- Maze* CreateMaze();
- //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
- {
- public:
- EnchantedMazeGame();
- virtual Room* MakeRoom(int n) const
- {
- return new EnchantedRoom(n);
- }
- virtual Door* MakeDoor(Room* r1,Room* r2) const
- {
- return new EnchantedDoor(r1,r2);
- }
- };
Factory.cpp
- #include <iostream>
- using namespace std;
- #include "Factory.h"
- string Direstr[Length] ={
- "North",
- "South",
- "East",
- "West"
- };
- Room::Room(int roomNo)
- {
- cout<<"Make "<<roomNo<<" room"<<endl;
- roomNumber = roomNo;
- }
- EnchantedRoom::EnchantedRoom(int roomNo):Room(roomNo)
- {
- cout<<"Make"<<roomNo<<"Enchanted room"<<endl;
- //roomNumber = roomNo;
- }
- void Room::SetSide(Direction dire,Mapsite* map)
- {
- cout<<"Build a Wall on Direction "<<Direstr[dire]<<endl;
- }
- void Room::Enter()
- {
- cout<<"Room enter"<<endl;
- }
- Wall::Wall()
- {
- cout<<"Make a wall"<<endl;
- }
- void Wall::Enter()
- {
- cout<<"Wall enter"<<endl;
- }
- void Door::Enter()
- {
- cout<<"Door enter"<<endl;
- }
- void Maze::AddRoom(Room *r)
- {
- cout<<"Add room to the maze!"<<endl;
- a[r->GetRoomNo()]=r;
- }
- Room* Maze::RoomNo(int roomNO) const
- {
- for (int i=0;i<MAX_ROOM_NO;i++)
- { if (i == roomNO)
- if (!a[i])
- return a[i];
- else
- return 0;
- }
- return 0;
- }
- Door::Door(Room* r1,Room* r2)
- {
- cout<<"A door is installed between 2 rooms"<<endl;
- }
- EnchantedDoor::EnchantedDoor(Room* r1,Room* r2)
- {
- cout<<"A Enchanted door is installed between 2 Enchanted Rooms"<<endl;
- }
- Maze* MazeGame::CreateMaze()
- {
- Maze* aMaze = MakeMaze();
- Room* r1 = MakeRoom(1);
- Room* r2 = MakeRoom(2);
- Door* theDoor = MakeDoor(r1,r2);
- aMaze->AddRoom(r1);
- aMaze->AddRoom(r2);
- r1->SetSide(North,MakeWall());
- r1->SetSide(East,theDoor);
- r1->SetSide(South,MakeWall());
- r1->SetSide(West,MakeWall());
- r2->SetSide(North,MakeWall());
- r2->SetSide(East,MakeWall());
- r2->SetSide(South,MakeWall());
- r2->SetSide(West,theDoor);
- return aMaze;
- }
- EnchantedMazeGame::EnchantedMazeGame()
- {
- cout<<"An enchantedMazegame is created!"<<endl;
- }
main.cpp
- #include <iostream>
- using namespace std;
- #include "Factory.h"
- int main()
- {
- MazeGame a;
- EnchantedMazeGame b;
- cout<<"Start MazeGame"<<endl;
- a.CreateMaze();
- cout<<"Start EnchantedMazeGame"<<endl;
- b.CreateMaze();
- return 0;
- }