6、工厂方法(Factory Method)举例:运用在建立迷宫中

工厂方法举例:运用在建立迷宫中

如下代码所示为运用了工厂模式之前和运用了工厂模式之后的情况。可以看出,运用工厂模式之前,这个函数对迷宫的布局进行硬编码,不灵活。

 

    假设想在一个包含施了魔法的迷宫的新游戏中重用一个已有的迷宫布局,而施了魔法的迷宫游戏有新的构件,如DoorNeedingSpell(一扇仅随着一个咒语才能被锁上和打开的门);以及EnchantedRoom(一个可以有不寻常东西的房间,比如魔法钥匙或是咒语),改变CreateMaze以让它用这些新类型的对象创建迷宫呢,最大障碍是对被实例化的类进行硬编码。

创建型模式提供了多种不同方法从实例化它们的代码中除去对这些具体类的显式引用。

enum Direction {North,East,South,West};

class MapSite{

public:

 virtual void Enter()=0;

};

class Room:public MapSite{

public:

 Room() {}

 Room(int aRoomNo) {}

 void SetSide(Direction aDir,MapSite *aMapSite) {}

 void Enter() {}

};

class Maze{

public:

 Maze() {}

 Room* RoomNo(int i) {return new Room;}

 void AddRoom(Room* aRoom) 

 {}

};

class Wall:public MapSite{

public:

 Wall() {}

    void Enter() {}

};

class Door:public MapSite{

public:

 Door(const Room *aRoom1,const Room *aRoom2) {}

 void Enter() {}

//private:

// Room* _room1;

// Room* _room2;

// bool _isOpen; 

};

class MazeGame{

public:

 MazeGame() {}

 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) {return new Door(r1,r2);}

 Maze* CreateMaze(); //硬编码

 Maze* CreateMazeByFactoryMethod();//运用工厂模式

};

class BomWall:public Wall{

public:

 BomWall() {}

};

class BomRoom:public Room{

public:

 BomRoom(int n) {}

};

class BomMazeGame:public MazeGame{

public: //有炸弹的迷宫

    BomMazeGame() {}

 Room* MakeRoom(int n)const {return new BomRoom(n);}

 Wall* MakeWall()const {return new BomWall;}

};

++++++++++++++++++硬编码++++++++++++++++

Maze* MazeGame::CreateMaze(){//硬编码

Maze* aMaze=new Maze;

Room* r1=new Room(1);

Room* r2=new Room(2);

Door* theDoor=new Door(r1,r2);

aMaze->AddRoom(r1);

aMaze->AddRoom(r2);

r1->SetSide(North,new Wall);

r1->SetSide(East,theDoor);

r1->SetSide(South,new Wall);

r1->SetSide(West,new Wall);

r2->SetSide(North,new Wall);

r2->SetSide(East,new Wall);

r2->SetSide(South,new Wall);

r2->SetSide(West,theDoor);

return aMaze;

}

+++++++++++++运用工厂模式+++++++++

Maze* MazeGame::CreateMazeByFactoryMethod(){//运用工厂模式

Maze* aMaze;

Room *r1,*r2;

Door* theDoor;

aMaze=MakeMaze();

r1=MakeRoom(1);

r2=MakeRoom(2);

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,MakeWall());

return aMaze;

}

+++++++++++++++++++++++++++++++++++++++++

void CFDlg::OnHardSoft() 

{

Maze* aMaze;

aMaze=new Maze;

//... 

}

void CFDlg::Onstandard() 

{

Maze* aMaze;

MazeGame* aGame;

aGame=new MazeGame;

aMaze=aGame->CreateMazeByFactoryMethod();

//... 

}

void CFDlg::Onbomb() 

{ //有炸弹的迷宫

Maze* aMaze;

MazeGame* aGame;

aGame=new BomMazeGame;

aMaze=aGame->CreateMazeByFactoryMethod();

//.... 

}

    由上实现可见,当要增加一个带炸弹的迷宫时,就将MazeGame派生一下。如:

class BombedMazeGame : public MazeGame {

public:

    virtual Wall* MakeWall()  const

        { return new BombedWall; }

    virtual Room* MakeRoom(int n)  const

        { return new RoomWithABomb(n); }

};

这样如果用BombedMazeGame的实例来CreateMaze,则生成的迷宫的Wall和Room就是Bombed。

然而,同时,这也面临一个问题,那就是,如果要增加一个带魔法的迷宫,则需要将MazeGame再派生一下,灵活性是增加了,而是类的种类也增加了。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值