您的位置:首页 > 其它

设计模式学习(三)抽象工厂

2010-05-27 10:23 603 查看
意图:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

适用性:

一个系统要独立于它的产品的创建,组合和表示时

一个产品要由多个产品系列中的一个来配置时

当你要强调一系列相关的产品对象的设计以便进行联合使用时

当你提供一个产品类库,而只想显示它们的接口而不是实现时

代码示例:

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

enum Direction{North, South, East, West};
class MapSite
{
public:
MapSite(){}
virtual ~MapSite(){}
virtual void Enter() = 0;
};
//Room
class Room:public MapSite
{
public:
Room(int);
void SetSite(Direction,MapSite*);
MapSite *GetSite(Direction) const;
virtual void Enter();
int GetRoomNum() const;
protected:
MapSite *mSite[4];
int      mRoomNumber;
};
Room::Room(int number):mRoomNumber(number)
{
mSite[0] = 0;//north
mSite[1] = 0;//south
mSite[2] = 0;//east
mSite[3] = 0;//west
cout<<"Constructor Room :"<<mRoomNumber<<endl;
}
void Room::Enter()
{
}
void Room::SetSite(Direction d, MapSite *map)
{
switch(d)
{
case North:
mSite[0] = map;
break;
case South:
mSite[1] = map;
break;
case East:
mSite[2] = map;
break;
case West:
mSite[3] = map;
break;
default:
break;
}
}
MapSite* Room::GetSite(Direction d) const
{
switch(d)
{
case North:
return mSite[0];
case South:
return mSite[1];
case East:
return mSite[2];
case West:
return mSite[3];
default:
return 0;
}
}
int Room::GetRoomNum() const
{
return mRoomNumber;
}
//EnchantedRoom
class EnchantedRoom: public Room
{
public:
EnchantedRoom(int n);
void Enter();
};
EnchantedRoom::EnchantedRoom(int n)
:Room(n)
{
cout<<"Constructor EnchantedRoom :"<<mRoomNumber<<endl;
}
void EnchantedRoom::Enter()
{
}
//RoomWithABomb
class RoomWithABomb: public Room
{
public:
RoomWithABomb(int n);
void Enter();
};
RoomWithABomb::RoomWithABomb(int n)
:Room(n)
{
cout<<"Constructor RoomWithABomb :"<<mRoomNumber<<endl;
}
void RoomWithABomb::Enter()
{
;
}

//Wall
class Wall:public MapSite
{
public:
Wall();
void Enter();
};
Wall::Wall()
{
cout<<"Constructor a Wall"<<endl;
}
void Wall::Enter()
{
}

//BombedWall
class BombedWall: public Wall
{
public:
BombedWall();
void Enter();
};
BombedWall::BombedWall()
:Wall()
{
cout<<"Constructor a BombedWall"<<endl;
}
void BombedWall::Enter()
{
}

//door
class Door:public MapSite
{
public:
Door(Room* =0, Room* =0);
void Enter();
Room* OtherSideFrom(Room*);
private:
Room *mRoom1;
Room *mRoom2;
bool mIsOpen;
};
Door::Door(Room *room1, Room *room2)
:mRoom1(room1)
,mRoom2(room2)
,mIsOpen(false)
{
cout<<"Constructor a Door"<<endl;
}
void Door::Enter()
{
}
Room* Door::OtherSideFrom(Room *room)
{
return 0;
}
//DoorNeedingSpell
class DoorNeedingSpell: public Door
{
public:
DoorNeedingSpell(Room* =0, Room* =0);
void Enter();
};
DoorNeedingSpell::DoorNeedingSpell(Room *r1, Room *r2)
:Door(r1,r2)
{
cout<<"Constructor DoorNeedingSpell/r/n";
}
void DoorNeedingSpell::Enter()
{
}
//maze
class Maze
{
public:
Maze();
void AddRoom(Room *);
Room* RoomNo(int) const;
private:
vector<Room*> *mRoomVec;
};
Maze::Maze()
:mRoomVec(new vector<Room*>)
{
}
void Maze::AddRoom(Room *room)
{
mRoomVec->push_back(room);
}
Room* Maze::RoomNo(int number) const
{
vector<Room*>::const_iterator it = mRoomVec->begin();
for(; it != mRoomVec->end(); ++it)
{
if((*it)->GetRoomNum() == number)
{
return (*it);
break;
}
}
return 0;
}
class MazeFactory
{
public:
MazeFactory(){}
virtual Maze* MakeMaze(){return new Maze;}
virtual Room* MakeRoom(int n){return new Room(n);}
virtual Door* MakeDoor(Room* r1, Room* r2){return new Door(r1,r2);}
virtual Wall* MakeWall(){return new Wall;}
};
class Spell;
class EnchantedMazeFactory :public MazeFactory
{
public:
EnchantedMazeFactory(){}
virtual Room* MakeRoom(int n){return new EnchantedRoom(n);}
virtual Door* MakeDoor(Room* r1, Room* r2){return new DoorNeedingSpell(r1,r2);}
protected:
Spell* CastSpell();
};
class BombedMazeFactory: public MazeFactory
{
public:
BombedMazeFactory(){}
virtual Room* MakeRoom(int n){return new RoomWithABomb(n);}
virtual Wall* MakeWall(){return new BombedWall;}
};
class MazeGame
{
public:
MazeGame(){}
virtual ~MazeGame(){}
Maze* CreateMaze(MazeFactory& factory);
};
Maze* MazeGame::CreateMaze(MazeFactory& factory)
{
Maze *aMaze = factory.MakeMaze();

Room* r1 = factory.MakeRoom(1);
Room* r2 = factory.MakeRoom(2);
Door *theDoor = factory.MakeDoor(r1, r2);
aMaze->AddRoom(r1);
aMaze->AddRoom(r2);
r1->SetSite(North, factory.MakeWall());
r1->SetSite(South, factory.MakeWall());
r1->SetSite(East, theDoor);
r1->SetSite(West, factory.MakeWall());
r2->SetSite(North, factory.MakeWall());
r2->SetSite(South, factory.MakeWall());
r2->SetSite(East, factory.MakeWall());
r2->SetSite(West, theDoor);
return aMaze;

}
int _tmain(int argc, _TCHAR* argv[])
{
MazeGame game;
MazeFactory factory;
game.CreateMaze(factory);
cout<<"/r/n";
EnchantedMazeFactory enchantedFactory;
game.CreateMaze(enchantedFactory);
cout<<"/r/n";
BombedMazeFactory bombedFactory;
game.CreateMaze(bombedFactory);
system("pause");
return 0;
}


MazeFactory 是一个完全由工厂方法组成的具体的类,通过生产一个子类并重新定义需要改变的操作,很容易生产一个新的MazeFactory.

创建迷宫的类MazeGame的创建迷宫的方法CreateMaze将MazeFactory作为一个参数,这样就可以很方便的指定需要创建哪一类型的房间,门和墙
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: