代码改变世界

威老迷宫探险第二季--如何更面向对象

2011-04-09 14:11  威老  阅读(1226)  评论(1编辑  收藏  举报

话说在第一季中,威老探访了乾陵,并成功地取回了大量的宝藏。

 

想看第一季的朋友请进

威老的迷宫探险第一季

 

这次,威老卷土重来,前往***。。等待他的将是什么样的危险呢?

去***的人,都再也没有回来过,相传在那里生活着一群吃人的Monster,它们每天都在四处游荡。任何访客一旦碰上Monster,就会立马被吃掉!

OK,这就是我们这次的迷宫。

 

经过分析,我们可以发现,Monster和Explorer是有许多的共性的。他们都能够做简单判断,看四周的情况,并且都能够移动。这些所以这些函数我们可以提取出来,做成类供Monster和Explorer调用,以提高代码的可重用性。

我首先想到创建一个名为"RouteChecker"的类,然后把IsEastWalkAble()、IsSouthWalkAble()、IsWestWalkAble()、IsNorthWalkAble()、IsWalkAble()这几个函数通通装到 "RouteChecker" 里。这样一来就算要添加新品种的Monster也都

可以调用这个类来判断其周围的情况了。

但是光是这样明显存在很大的缺陷,如果我现在想要扩展一下RouteChecker类,那我就只能打开RouteChecker的代码进行修改,这明显违背了面向对象的基本原则之一:开放封闭原则。为了尽量封闭原本的代码,我引入了简单工厂模式。

以下便是使用了简单工厂模式之后的类图。

 

对RouteChecker类应用简单工厂模式之后获得的类图

 

 

 

根据这个模型获得代码。

以下是RouteChecker类:

 

/*routeChecker.h*/
/*路径检查类
功能:
//检查是否已经到达终点
//检查东面是否可行走
//检查南面是否可行走
//检查西面是否可行走
//检查北面是否可行走

*/
#ifndef _ROUTECHECKER_H
#define _ROUTECHECKER_H

#include
"maze.h"

/*
类名:RouteChecker
功能:检查路况
*/
class RouteChecker
{
private:

public:
    RouteChecker(){};
    RouteChecker(Maze 
* Checked_Maze, int x, int y);
    
virtual bool Check(){return true;};                                //检查
    void setCheckedMaze(Maze * ch_Maze)            //设置要检查的迷宫
    {
        checked_Maze 
= ch_Maze;
    };
    
void setCheckedPosition(int ch_x, int ch_y)//设置要检查的位置
    {
        checked_x 
= ch_x;
        checked_y 
= ch_y;
    };
//    int searchAround();        //搜索四周,以寻找下一个路径点。四个方向东、南、西、北。
                            
//分别返回1、2、3、4,无路可走返回-1,到达终点返回0。
protected:
    Maze 
* checked_Maze;
    
int checked_x,checked_y;
    
bool checkWalkable(int x, int y);    //检查指定位置是否可行走
};

/*
类名:ExitChecker
功能:检查是否已经到达终点
*/
class ExitChecker : public RouteChecker
{
public:
    ExitChecker(){};
    
bool Check();
};

/*
类名:EastChecker
功能:检查东面是否可行走
*/
class EastChecker : public RouteChecker
{
public:
    EastChecker (){};
    
bool Check();
};
//
//。。。。。略去一些代码
//
/*

类名:NorthChecker
功能:检查北面是否可行走
*/
class NorthChecker : public RouteChecker
{
public:
    NorthChecker(){};
    
bool Check();
};
#endif
/*routeChecker.cpp*/
/*路径检查类
功能:分别检查各个方向是否可以行走。
*/
#include
"routeChecker.h"

RouteChecker::RouteChecker(Maze 
* Checked_Maze, int x, int y)
{
    checked_Maze 
= Checked_Maze;
    checked_x 
= x;
    checked_y 
= y;
}

/*
功能:检查位置(x,y)是否可行走
*/
bool RouteChecker::checkWalkable(int x, int y)
{
    
if(checked_Maze->getSquareType(x, y) == '0')
        
return true;
    
else
        
return false;
}


/*
功能:检查是否已经到达终点
*/
bool ExitChecker::Check()
{
    
if( (checked_Maze->getexit_x() == checked_x) && (checked_Maze->getexit_y() == checked_y) )
    {
        
return true;
    }
    
else
        
return false;
}

/*
功能:检查东面是否可行走
*/
bool EastChecker::Check()
{
    
if(checkWalkable(checked_x+1, checked_y))
    {
        
return true;
    }
    
else
        
return false;
}
//
//。。。。。略去一些
//
/*

功能:检查北面是否可行走
*/
bool NorthChecker::Check()
{
    
if(checkWalkable(checked_x,checked_y-1))
    {
        
return true;
    }
    
else
        
return false;
}
以下是工厂类:
 
/*
类名:RouteCheckerFactory
功能:RouteChecker工厂类,负责创建具体类型的RouteChecker
*/

#ifndef _ROUTECHECKERFACTORY_H
#define _ROUTECHECKERFACTORY_H

#include
"routeChecker.h"

class RouteCheckerFactory
{
public:
    RouteChecker
* Create(int direction);
};

#endif
 
/*
类名:RouteCheckerFactory
功能:RouteChecker工厂类,负责创建具体类型的RouteChecker
*/

#include
"RouteCheckerFactory.h"

RouteChecker
* RouteCheckerFactory::Create(int direction)
{
    RouteChecker 
*rc;
    
switch(direction)
    {
    
case 0:    rc = new ExitChecker();            break;//出口
    case 1:    rc = new EastChecker();            break;//
    case 2:    rc = new SouthChecker();        break;//
    case 3:    rc = new WestChecker();            break;//西
    case 4:    rc = new NorthChecker();        break;//
    }
    
return rc;
};
修改了Explorer类: 
int Explorer::searchAround()
{
    RouteChecker 
* rc;
    RouteCheckerFactory rcf;
    
for(int i=0; i<=4; i++)
    {
        rc 
= rcf.Create(i);
        rc
->setCheckedMaze(explored_Maze);
        rc
->setCheckedPosition(current_x,current_y);
        
if(rc->Check() == true)
            
return i;
    }
    
return -1;
}

 

/* 这几个方法注释掉
bool IsInExit();        //检查是否已经到达终点 
bool IsEastWalkable();    //检查东面是否可行走 
bool IsSouthWalkable();    //检查南面是否可行走 
bool IsWestWalkable();    //检查西面是否可行走 
bool IsNorthWalkable();    //检查北面是否可行走 
bool checkWalkable(int x, int y);    //检查指定位置是否可行走 
*/

当然,程序的运行结果跟之前是完全一样的,但是就代码的质量来讲,这是上一个版本所无法比拟的。

 

做完这一切之后。。。我才发现又囧了searchAround()似乎也应该提取出来封装进RouteChecker.h里才好。而WalkTo()、walkToNext()、walkTowards(int direction)、goBack()这些也应该一并封装才是。

想到这里,我崩溃了。。。要知道我光是封装、测试Routechecker就搞了5个小时啊。。。

Monster还未出现,威老就要挂了!@#¥%……

不行,得想些其他的办法。。。