状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态发生变化时,动态地改变其行为。该模式的核心在于将状态相关的行为封装到独立的状态类中,使得对象的行为随状态而变化,从而减少冗余的条件判断。
以下是一个简单的状态模式示例,模拟一个怪物的状态变化。
MonsterStatus
是一个抽象类,定义了所有具体状态类必须实现的接口。Attacked
方法用于处理怪物被攻击的逻辑,接受攻击力和怪物对象的引用。//怪物状态类的父类
class MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj) = 0;
virtual ~MonsterStatus() {}
};
MonsterStatus
,并实现 Attacked
方法。//凶悍状态类
class MonsterStatus_Feroc :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Feroc* getInstance()
{
static MonsterStatus_Feroc instance;
return &instance;
}
};
//不安状态类
class MonsterStatus_Worr :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Worr* getInstance()
{
static MonsterStatus_Worr instance;
return &instance;
}
};
//恐惧状态类
class MonsterStatus_Fear :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Fear* getInstance()
{
static MonsterStatus_Fear instance;
return &instance;
}
};
//死亡状态类
class MonsterStatus_Dead :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Dead* getInstance()
{
static MonsterStatus_Dead instance;
return &instance;
}
};
Monster
类作为上下文类,持有当前状态的引用。checkAndSwitchState
方法用于根据当前生命值判断并切换状态。Attacked
方法调用当前状态的 Attacked
方法。//怪物类
class Monster
{
public:
Monster(int life);
~Monster();
public:
void Attacked(int power); //怪物被攻击
public:
int GetLife() //获取怪物血量
{
return m_life;
}
void SetLife(int life) //设置怪物血量
{
m_life = life;
}
MonsterStatus* getCurrentState() //获取怪物当前状态
{
return m_pState;
}
void setCurrentState(MonsterStatus* pstate) //设置怪物当前状态
{
m_pState = pstate;
}
private:
int m_life; //血量(生命值)
MonsterStatus* m_pState; //持有状态对象
};
int main()
{
Monster monster(500);
cout << "怪物出生,当前处于凶悍状态,500点血!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
return 0;
}
Monster
类充当上下文,负责管理当前状态并委托请求给当前状态对象。MonsterStatus
是抽象状态类,声明了状态相关的方法(如 Attacked
),具体状态类需要实现这些方法。MonsterStatus_Feroc
、MonsterStatus_Worr
、MonsterStatus_Fear
和 MonsterStatus_Dead
)实现了不同的 Attacked
方法,表现出不同的行为。对象的行为依赖于其状态,并且可以在运行时改变状态。
需要避免使用大量条件语句来管理对象的状态。
状态的改变会影响到对象的多个方法。
行为依赖于状态:对象的行为依赖于其状态,并且可以在运行时改变状态。
避免条件语句:需要避免使用大量条件语句来管理对象的状态,特别是在状态和行为较多的情况下。
状态影响多个方法:状态的改变会影响到对象的多个方法,适合使用状态模式来管理这些变化。
#ifndef __MONSTER__
#define __MONSTER__
class MonsterStatus; //类前向声明
//怪物类
class Monster
{
public:
Monster(int life);
~Monster();
public:
void Attacked(int power); //怪物被攻击
public:
int GetLife() //获取怪物血量
{
return m_life;
}
void SetLife(int life) //设置怪物血量
{
m_life = life;
}
MonsterStatus* getCurrentState() //获取怪物当前状态
{
return m_pState;
}
void setCurrentState(MonsterStatus* pstate) //设置怪物当前状态
{
m_pState = pstate;
}
private:
int m_life; //血量(生命值)
MonsterStatus* m_pState; //持有状态对象
};
#endif
#include
#include "Monster.h"
#include "MonsterStatus.h"
using namespace std;
//构造函数,怪物的初始状态从“凶悍”开始
Monster::Monster(int life) :m_life(life), m_pState(nullptr)
{
m_pState = MonsterStatus_Feroc::getInstance();
}
//析构函数
Monster::~Monster(){}
//怪物被攻击
void Monster::Attacked(int power)
{
m_pState->Attacked(power, this);
}
#ifndef __MONSTERSTATUS__
#define __MONSTERSTATUS__
class Monster; //类前向声明
//怪物状态类的父类
class MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj) = 0;
virtual ~MonsterStatus() {}
};
//凶悍状态类
class MonsterStatus_Feroc :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Feroc* getInstance()
{
static MonsterStatus_Feroc instance;
return &instance;
}
};
//不安状态类
class MonsterStatus_Worr :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Worr* getInstance()
{
static MonsterStatus_Worr instance;
return &instance;
}
};
//恐惧状态类
class MonsterStatus_Fear :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Fear* getInstance()
{
static MonsterStatus_Fear instance;
return &instance;
}
};
//死亡状态类
class MonsterStatus_Dead :public MonsterStatus
{
public:
virtual void Attacked(int power, Monster* mainobj);
public:
static MonsterStatus_Dead* getInstance()
{
static MonsterStatus_Dead instance;
return &instance;
}
};
#endif
#include
#include "Monster.h"
#include "MonsterStatus.h"
using namespace std;
//各个状态子类的Attacked成员函数实现代码
void MonsterStatus_Feroc::Attacked(int power, Monster* mainobj)
{
int orglife = mainobj->GetLife(); //暂存原来的怪物血量值用于后续比较
if ((orglife - power) > 400) //怪物原来处于凶悍状态,现在依旧处于凶悍状态
{
//状态未变
mainobj->SetLife(orglife - power); //怪物剩余的血量
cout << "怪物处于凶悍状态中,对主角进行疯狂的反击!" << std::endl;
//处理其他动作逻辑比如反击
}
else
{
//不管下个状态是啥,总之不会是凶悍状态,只可能是不安、恐惧、死亡状态之一,先无条件转到不安状态去(不安状态中会进行再次判断)
mainobj->setCurrentState(MonsterStatus_Worr::getInstance());
mainobj->getCurrentState()->Attacked(power, mainobj);
}
}
void MonsterStatus_Worr::Attacked(int power, Monster* mainobj)
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 100) //怪物原来处于不安状态,现在依旧处于不安状态
{
//状态未变
mainobj->SetLife(orglife - power); //怪物剩余的血量
cout << "怪物处于不安状态中,对主角进行反击并呼唤支援!" << std::endl;
//处理其他动作逻辑比如反击和不停的呼唤支援
}
else
{
//不管下个状态是啥,总之不会是凶悍和不安状态,只可能是恐惧、死亡状态之一,先无条件转到恐惧状态去
mainobj->setCurrentState(MonsterStatus_Fear::getInstance());
mainobj->getCurrentState()->Attacked(power, mainobj);
}
}
void MonsterStatus_Fear::Attacked(int power, Monster* mainobj)
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 0) //怪物原来处于恐惧状态,现在依旧处于恐惧状态
{
//状态未变
mainobj->SetLife(orglife - power); //怪物剩余的血量
cout << "怪物处于恐惧状态中,处于逃跑之中!" << std::endl;
//处理其他动作逻辑比如逃跑
}
else
{
//不管下个状态是啥,总之不会是凶悍、不安和恐惧状态,只可能是死亡状态
mainobj->setCurrentState(MonsterStatus_Dead::getInstance());
mainobj->getCurrentState()->Attacked(power, mainobj);
}
}
void MonsterStatus_Dead::Attacked(int power, Monster* mainobj)
{
int orglife = mainobj->GetLife();
if (orglife > 0)
{
//还要把怪物生命值减掉
mainobj->SetLife(orglife - power); //怪物剩余的血量
//处理怪物死亡后事宜比如怪物尸体定时消失等
}
cout << "怪物死亡!" << std::endl;
}
#include
#include "Monster.h"
using namespace std;
int main()
{
Monster monster(500);
cout << "怪物出生,当前处于凶悍状态,500点血!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
return 0;
}
物剩余的血量
//处理怪物死亡后事宜比如怪物尸体定时消失等
}
cout << “怪物死亡!” << std::endl;
}
#### 5. main.cpp
```cpp
#include
#include "Monster.h"
using namespace std;
int main()
{
Monster monster(500);
cout << "怪物出生,当前处于凶悍状态,500点血!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
return 0;
}