1. 状态模式的核心价值与应用场景
状态模式是行为设计模式中的一种,它允许对象在其内部状态改变时改变其行为。这种模式特别适合处理那些对象行为依赖于其状态,并且状态转换复杂的场景。想象一下电梯控制系统:电梯有开门、关门、运行、停止等多种状态,每种状态下对相同按钮的响应完全不同。如果用传统的if-else或switch-case来处理,代码会变得难以维护。
在C++中实现状态模式,我们通常会将状态相关的行为抽取到独立的类中,让原始对象(称为Context)将工作委派给当前状态对象。这样做有几个显著优势:
- 消除了庞大的条件分支语句,使代码更易维护
- 将状态转换逻辑集中管理,而不是分散在代码各处
- 新的状态可以很容易地添加,符合开闭原则
- 每个状态的行为被封装在单独的类中,更符合单一职责原则
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 状态模式的经典实现结构
2.1 基础类设计
典型的C++状态模式实现包含三个核心组件:
cpp复制// 前置声明
class Context;
// 抽象状态类
class State {
protected:
Context* context_;
public:
virtual ~State() = default;
void set_context(Context* context) {
this->context_ = context;
}
virtual void Handle1() = 0;
virtual void Handle2() = 0;
};
// 上下文类
class Context {
private:
State* state_;
public:
Context(State* state) : state_(nullptr) {
this->TransitionTo(state);
}
~Context() {
delete state_;
}
void TransitionTo(State* state) {
if (this->state_ != nullptr)
delete this->state_;
this->state_ = state;
this->state_->set_context(this);
}
void Request1() {
this->state_->Handle1();
}
void Request2() {
this->state_->Handle2();
}
};
2.2 具体状态实现
具体状态类继承自抽象状态类,实现特定状态下的行为:
cpp复制class ConcreteStateA : public State {
public:
void Handle1() override;
void Handle2() override {
std::cout << "ConcreteStateA处理请求2\n";
}
};
class ConcreteStateB : public State {
public:
void Handle1() override {
std::cout << "ConcreteStateB处理请求1\n";
}
void Handle2() override {
std::cout << "ConcreteStateB处理请求2\n";
std::cout << "ConcreteStateB希望改变上下文状态\n";
this->context_->TransitionTo(new ConcreteStateA);
}
};
void ConcreteStateA::Handle1() {
std::cout << "ConcreteStateA处理请求1\n";
std::cout << "ConcreteStateA希望改变上下文状态\n";
this->context_->TransitionTo(new ConcreteStateB);
}
3. 状态模式在游戏开发中的实战应用
游戏开发是状态模式的典型应用场景。以角色状态管理为例,一个游戏角色可能有站立、行走、奔跑、跳跃、攻击等多种状态,每种状态下对玩家输入的反应各不相同。
3.1 游戏角色状态设计
cpp复制class CharacterState {
protected:
Character* character_;
public:
virtual ~CharacterState() = default;
void set_character(Character* character) {
this->character_ = character;
}
virtual void HandleInput(Input input) = 0;
virtual void Update() = 0;
};
class StandingState : public CharacterState {
public:
void HandleInput(Input input) override {
if (input == PRESS_LEFT || input == PRESS_RIGHT) {
character_->ChangeState(new WalkingState);
} else if (input == PRESS_UP) {
character_->ChangeState(new JumpingState);
}
}
void Update() override {
// 站立状态的特殊逻辑
}
};
class WalkingState : public CharacterState {
public:
void HandleInput(Input input) override {
if (input == RELEASE_LEFT || input == RELEASE_RIGHT) {
character_->ChangeState(new StandingState);
} else if (input == PRESS_SHIFT) {
character_->ChangeState(new RunningState);
}
}
void Update() override {
// 行走状态的特殊逻辑
}
};
