状态模式(State Pattern)是行为型设计模式,其核心在于允许对象在内部状态改变时改变行为,使对象呈现出动态的类特性变化。该模式如同变色龙的皮肤——当环境改变时,其行为特征自动适配新状态。
模式三要素
上下文(Context):维护当前状态对象(如电梯控制器);
抽象状态(State):定义状态接口规范(如电梯运行/停止接口);
具体状态(ConcreteState):实现特定状态行为(如电梯上升状态);
与策略模式的区别
维度 | 状态模式 | 策略模式 |
---|---|---|
目标 | 管理对象内部状态转换 | 灵活替换算法策略 |
状态关联性 | 状态间存在逻辑关联和转换条件 | 策略之间通常相互独立 |
生命周期 | 状态常由上下文自动切换 | 策略由客户端显式指定 |
1. 状态转换机制
上下文对象通过持有状态接口指针实现动态行为切换。当触发事件时,当前状态对象处理请求并可能触发状态迁移:
// 抽象状态类
class ElevatorState {
public:
virtual void openDoor(ElevatorContext& ctx) = 0;
virtual void closeDoor(ElevatorContext& ctx) = 0;
virtual ~ElevatorState() = default;
};
// 具体状态:停止状态
class StoppedState : public ElevatorState {
public:
void openDoor(ElevatorContext& ctx) override {
cout << "开门操作" << endl;
ctx.setState(new OpenedState()); // 状态转换
}
// 其他方法实现...
};
2. 多态行为封装
每个具体状态类实现完整的行为集合,通过将条件判断转换为对象类型判断,消除复杂的if-else分支。例如电梯运行状态下:
class RunningState : public ElevatorState {
public:
void closeDoor(ElevatorContext& ctx) override {
cout << "运行中禁止关门操作" << endl; // 特定状态下的行为限制
}
};
3. 状态生命周期管理
推荐使用智能指针实现自动内存管理:
class ElevatorContext {
private:
std::unique_ptr<ElevatorState> currentState;
public:
void setState(std::unique_ptr<ElevationState> newState) {
currentState = std::move(newState);
}
};
1. 游戏角色行为控制
实现角色不同状态(站立/跳跃/下蹲)的行为差异:
class CharacterState {
public:
virtual void handleInput(Character& c, InputType input) = 0;
virtual void update(Character& c) = 0;
};
// 跳跃状态处理重力影响
class JumpingState : public CharacterState {
public:
void update(Character& c) override {
c.velocityY -= GRAVITY;
if(c.positionY <= 0)
c.setState(new StandingState());
}
};
2. 订单流程管理
电商订单状态流转示例:
class OrderState {
public:
virtual void cancel(Order& order) = 0;
virtual void pay(Order& order) = 0;
};
// 已支付状态禁止重复支付
class PaidState : public OrderState {
public:
void pay(Order& order) override {
throw std::logic_error("订单已支付");
}
};
3. 网络协议处理
TCP连接状态管理:
class TCPState {
public:
virtual void transmit(Connection& conn, Packet pkt) = 0;
};
class EstablishedState : public TCPState {
public:
void transmit(Connection& conn, Packet pkt) override {
// 正常数据传输逻辑
if(pkt.isFIN())
conn.setState(new ClosingState());
}
};
步骤1:定义状态接口
class ATMState {
public:
virtual void insertCard(ATMMachine& machine) = 0;
virtual void enterPin(ATMMachine& machine, int pin) = 0;
virtual void ejectCard(ATMMachine& machine) = 0;
virtual ~ATMState() = default;
};
步骤2:实现具体状态
class NoCardState : public ATMState {
public:
void insertCard(ATMMachine& machine) override {
cout << "卡片已插入" << endl;
machine.setState(std::make_unique<HasCardState>());
}
// 其他方法抛出异常...
};
class HasCardState : public ATMState {
public:
void enterPin(ATMMachine& machine, int pin) override {
if(validate(pin)) {
machine.setState(std::make_unique<LoggedInState>());
}
}
};
步骤3:构建上下文类
class ATMMachine {
private:
std::unique_ptr<ATMState> currentState;
int cashAmount = 10000;
public:
ATMMachine() : currentState(std::make_unique<NoCardState>()) {}
void setState(std::unique_ptr<ATMState> newState) {
currentState = std::move(newState);
}
void requestWithdraw(int amount) {
if(amount <= cashAmount) {
cashAmount -= amount;
}
}
};
// 状态表驱动示例
std::map<StateID, std::function<void()>> stateTable = {
{STATE_A, []{ /* 行为A */ }},
{STATE_B, []{ /* 行为B */ }}
};
// 前向声明
class ConcreteStateB;
class ConcreteStateA : public State {
public:
void handle(Context& ctx) override {
ctx.changeState(std::make_unique<ConcreteStateB>());
}
};
std::mutex stateMutex;
void SafeStateChange(Context& ctx, StatePtr newState) {
std::lock_guard<std::mutex> lock(stateMutex);
ctx.setState(std::move(newState));
}
模式优势分析
演进方向
// 使用variant实现类型安全状态管理
using State = std::variant<IdleState, WorkingState, ErrorState>;
适用性建议
状态模式如同软件系统的神经中枢,通过巧妙的职责划分实现行为的智能适配。掌握该模式,可使开发者在处理复杂状态逻辑时事半功倍。建议结合具体业务场景,灵活运用模式变体(如分层状态机),以实现更优雅的设计。