【适用性】
(1)一个系统要独立于它的产品的创建、组合和表示时;
(2)一个系统要有多个产品系列中的一个来配置时;
(3)当你要强调一系列相关的产品对象的设计以便进行联合使用时;
(4)当你提供一个产品类库,而只想显示它们的接口而不是实现时。
【引用】
ABSTRACT FACTORY—追MM少不了请吃饭了,麦当劳的套餐和肯德基的套餐都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“两个B套餐”就行了。麦当劳和肯德基就是B套餐的Absctract Factory, B套餐里含有汉堡, 鸡翅和饮料. 麦当劳或肯德基会根据B套餐的规格, 让汉堡Factory, 鸡翅Factory, 饮料Factory分别生产对应B套餐的材料.
抽象工厂模式:客户类和工厂类分开。消费者任何时候需要某套产品集合时,只需向抽象工厂请求即可。抽象工厂会再向具体的工厂生产出符合产品集规格的产品.
【代码示范】
/*
MapSite是所以迷宫组件的公共抽象类
*/
enum Direction{North,South,East,West};
class MapSite{
public:
virtual void Enter() = 0;
};
class Door : public MapSite{
public:
Door(Room* = 0, Room* = 0);
virtual void Enter();
Room* otherSideFrom(Room*);
private:
Room* _room1;
Room* _room2;
bool _isOpen;
};
class Wall : public MapSite{
public:
Wall();
virtual void Enter();
};
class Room : public MapSite{
public:
Room(int roomNo);
MapSite* GetSide(Direction)const;
void setSide(Direction,MapSite*);
virtual void Enter();
private:
MapSite* _sides[4];
int _roomNumber;
};
/*
Maze类表示房间集合
*/
const int totalNum = 10;
class Maze{
public:
Maze();
void AddRoom(Room*);
Room* RoomNo(int)const;
private:
//...
Room* room[totalNum][totalNum];
};
/*
创建迷宫的组件
*/
class MazeFactory{
public:
MazeFactory(){}
virtual Maze* makeMaze()const{
return new Maze;
}
virtual Wall* makeWall()const{
return new Wall;
}
virtual Room* makeRoom(int n)const{
return new Room(n);
}
virtual Door* makeDoor(Room* r1, Room* r2)const{
return new Door(r1,r2);
}
};
/*
创建迷宫
*/
class MazeGame{
public:
MazeGame();
Maze* createMaze(MazeFactory& factory);
};
/*
以MazeFactory为参数,来创建房间、墙壁和门,可以传递不同的参数来改变房间、墙壁和门的类。
避免了对类名进行硬编码.
【思考】假设你想在一个包含施了魔法的迷宫的新游戏中重用一个已有的迷宫布局,施了魔法的迷宫游戏有新的构建。你怎么才能较容易的改变CreateMaze以让它用这些新类型的对象来创建迷宫呢?
例如硬编码函数是这样createMaze(){
Maze* aMaze = new Maze();
Room* r1 = new Room;
Room* r2 = new Room;
Door* aDoor = new Door(r1,r2);
aMaze->AddRoom (r1);
aMaze->AddRoom (r2);
r1->setSide (North,new wall);
.....
return aMaze;
}
*/
【抽象工厂修改后的程序】
Maze* MazeGame::createMaze(MazeFactory& factory){
Maze* aMaze = factory.makeMaze();
Room* r1 = factory.makeRoom(1);
Room* r2 = factory.makeRoom(2);
Door* aDoor = factory.makeDoor (r1,r2);
aMaze->AddRoom (r1);
aMaze->AddRoom (r2);
r1->setSide (North,factory.makeWall ());
r1->setSide (East,aDoor);
r1->setSide (South,factory.makeWall ());
r1->setSide (West,factory.makeWall ());
r2->setSide (North,factory.makeWall());
r2->setSide (East,factory.makeWall ());
r2->setSide (South,factory.makeWall ());
r2->setSide (West,aDoor);
return aMaze;
}
【应用】
class BomedMazeFactory: public MazeGame
{
BomedMazeFactory();
Wall* MakeWall();
Room* MakeRoom();
};
MazeGame game;
BomedMazeFactory factory;
game.CreateMaze(factory);//前面的辛苦,就是为了这里的方便