状态模式(State Pattern)是一种行为设计模式,它允许一个对象在内部状态改变时改变其行为 ,使对象看起来像是改变了其类。
核心概念
设计原则
状态模式遵循以下设计原则:
-
单一职责原则:将状态相关行为分离到不同类中
-
开闭原则:可以新增状态而不修改现有代码
-
封装性:状态转换逻辑封装在状态类中
主要优点
-
清晰状态转换:将状态转换逻辑组织化
-
减少条件语句:消除庞大的条件状态判断
-
可扩展性:容易添加新状态和转换
-
行为局部化:状态特定行为集中在对应状态类中
模式结构
主要组件
-
Context(上下文)
-
维护当前状态的引用
-
将状态相关请求委托给当前状态对象
-
-
State(状态接口)
-
定义状态接口
-
封装与Context特定状态相关的行为
-
-
ConcreteState(具体状态)
-
实现状态接口
-
每个子类实现与Context状态相关的行为
-
完整代码示例
#include <iostream>
#include <memory>
#include <string>
// 前置声明
class State;
// ==================== 上下文类 ====================
class Player {
std::unique_ptr<State> state_;
std::string name_;
public:
explicit Player(const std::string& name);
void setState(std::unique_ptr<State> state);
std::string getName() const;
// 玩家行为
void play();
void pause();
void stop();
void lock();
void unlock();
};
// ==================== 状态接口 ====================
class State {
public:
virtual ~State() = default;
virtual void play(Player* player) = 0;
virtual void pause(Player* player) = 0;
virtual void stop(Player* player) = 0;
virtual void lock(Player* player) = 0;
virtual void unlock(Player* player) = 0;
protected:
void changeState(Player* player, std::unique_ptr<State> state) {
player->setState(std::move(state));
}
};
// ==================== 具体状态 ====================
class ReadyState : public State {
public:
void play(Player* player) override;
void pause(Player* player) override { /* 无效操作 */ }
void stop(Player* player) override { /* 无效操作 */ }
void lock(Player* player) override;
void unlock(Player* player) override { /* 已在解锁状态 */ }
};
class PlayingState : public State {
public:
void play(Player* player) override { /* 已在播放状态 */ }
void pause(Player* player) override;
void stop(Player* player) override;
void lock(Player* player) override;
void unlock(Player* player) override { /* 无效操作 */ }
};
class PausedState : public State {
public:
void play(Player* player) override;
void pause(Player* player) override { /* 已在暂停状态 */ }
void stop(Player* player) override;
void lock(Player* player) override;
void unlock(Player* player) override { /* 无效操作 */ }
};
class LockedState : public State {
public:
void play(Player* player) override { /* 锁定状态下不能播放 */ }
void pause(Player* player) override { /* 锁定状态下不能暂停 */ }
void stop(Player* player) override { /* 锁定状态下不能停止 */ }
void lock(Player* player) override { /* 已在锁定状态 */ }
void unlock(Player* player) override;
};
// ==================== 上下文方法实现 ====================
Player::Player(const std::string& name) : name_(name) {
state_ = std::make_unique<ReadyState>();
}
void Player::setState(std::unique_ptr<State> state) {
state_ = std::move(state);
}
std::string Player::getName() const {
return name_;
}
void Player::play() {
state_->play(this);
}
void Player::pause() {
state_->pause(this);
}
void Player::stop() {
state_->stop(this);
}
void Player::lock() {
state_->lock(this);
}
void Player::unlock() {
state_->unlock(this);
}
// ==================== 具体状态方法实现 ====================
void ReadyState::play(Player* player) {
std::cout << player->getName() << ": 开始播放" << std::endl;
changeState(player, std::make_unique<PlayingState>());
}
void ReadyState::lock(Player* player) {
std::cout << player->getName() << ": 锁定播放器" << std::endl;
changeState(player, std::make_unique<LockedState>());
}
void PlayingState::pause(Player* player) {
std::cout << player->getName() << ": 暂停播放" << std::endl;
changeState(player, std::make_unique<PausedState>());
}
void PlayingState::stop(Player* player) {
std::cout << player->getName() << ": 停止播放" << std::endl;
changeState(player, std::make_unique<ReadyState>());
}
void PlayingState::lock(Player* player) {
std::cout << player->getName() << ": 锁定播放器" << std::endl;
changeState(player, std::make_unique<LockedState>());
}
void PausedState::play(Player* player) {
std::cout << player->getName() << ": 恢复播放" << std::endl;
changeState(player, std::make_unique<PlayingState>());
}
void PausedState::stop(Player* player) {
std::cout << player->getName() << ": 停止播放" << std::endl;
changeState(player, std::make_unique<ReadyState>());
}
void PausedState::lock(Player* player) {
std::cout << player->getName() << ": 锁定播放器" << std::endl;
changeState(player, std::make_unique<LockedState>());
}
void LockedState::unlock(Player* player) {
std::cout << player->getName() << ": 解锁播放器" << std::endl;
changeState(player, std::make_unique<ReadyState>());
}
// ==================== 客户端代码 ====================
int main() {
std::cout << "=== 状态模式演示: 音乐播放器 ===" << std::endl;
Player player("我的播放器");
// 正常流程
player.play();
player.pause();
player.play();
player.stop();
// 锁定测试
std::cout << "\n测试锁定功能:" << std::endl;
player.play();
player.lock();
player.play(); // 应该无效
player.unlock();
player.play();
// 无效操作测试
std::cout << "\n测试无效操作:" << std::endl;
player.stop();
player.stop(); // 应该无效
player.pause(); // 应该无效
return 0;
}
模式变体
1. 状态表驱动
class StateMachine {
std::unordered_map<std::string,
std::unordered_map<std::string,
std::function<void()>>> transitions_;
std::string currentState_;
public:
void addTransition(const std::string& from, const std::string& event,
const std::string& to, std::function<void()> action) {
transitions_[from][event] = [this, to, action] {
action();
currentState_ = to;
};
}
void handleEvent(const std::string& event) {
auto& stateTransitions = transitions_[currentState_];
if (stateTransitions.find(event) != stateTransitions.end()) {
stateTransitions[event]();
}
}
};
2. 共享状态对象
class SharedState : public State {
// 可以共享的状态数据
};
class ConcreteStateA : public SharedState {
// 实现特定行为
};
// 使用时可以共享同一个状态实例
auto sharedState = std::make_shared<ConcreteStateA>();
context1.setState(sharedState);
context2.setState(sharedState);
实际应用场景
-
工作流引擎:如订单状态流转
-
游戏开发:角色行为状态管理
-
UI系统:控件不同状态下的行为
-
网络协议:协议状态机实现
-
硬件控制:设备状态管理