21行为型设计模式——状态模式

一、状态模式介绍

状态模式(State Pattern)是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,使对象看起来好像修改了其类。通过将状态行为封装在状态对象中,状态模式将对象的状态与其行为解耦,从而使得在状态变化时,代码的可维护性和可扩展性提高。

状态模式的结构图

  1. Context(上下文)

    • 上下文类,通常包含一个指向当前状态的引用,并且有一个方法来改变状态。它会调用当前状态的行为。
  2. State(状态接口或抽象类)

    • 声明一个接口或抽象类,这个接口或抽象类定义了具体状态类所需的操作。
  3. ConcreteState(具体状态类)

    • 实现状态接口或继承自状态抽象类,定义具体的状态行为。每个具体状态类封装了与该状态相关的行为。

二、状态模式的设计方法

假设我们有一个简单的订单处理系统,不同的订单状态(如待处理、已发货、已完成)需要不同的行为。使用状态模式可以将这些行为分离到不同的状态类中。

state.cpp

cpp 复制代码
#include <iostream>
#include <string>

// 状态接口
class State {
public:
	virtual void handleRequest() = 0;
};

// 具体状态
class PendingState : public State {
public:
	void handleRequest() {
		std::cout << "订单正在处理.\n"; 
	}
};

// 具体状态
class ConfirmState : public State {
public:
	void handleRequest() override {
		std::cout << "商家已接单.\n";
	}
};

// 具体状态
class ShippedState : public State {
public:
	void handleRequest() override {
		std::cout << "商品(订单)运输中.\n";
	}
};

// 具体状态
class ReceivedState : public State {
public:
	void handleRequest() override {
		std::cout << "客户收到货.\n";
	}
};

// 上下文
class OrderContext {
public:
	OrderContext(State* state) : currentState(state) {}	
	
	void setState(State* state) {
		currentState = state;
	}
	
	void request() {
		currentState->handleRequest();
	}
	
private:
	State* currentState;
};

void doWorking() {
	PendingState  pending;
	ConfirmState confirm;
	ShippedState shipped;
	ReceivedState received;
	
	OrderContext order(&pending);
	order.request();	// 模拟订单系统的处理行为
	order.setState(&confirm);
	order.request();
	order.setState(&shipped);
	order.request();
	order.setState(&received);
	order.request();
	return;
}

int main() {

	doWorking();
	return 0;
}

运行效果

三、状态模式的应用场景

1. 工作流管理

场景描述: 在工作流系统中,任务或流程可能有多种状态,例如"待审批"、"审批中"、"已完成"等。每个状态下的操作和行为可能不同。

应用示例: 使用状态模式可以定义不同的状态类(如PendingState,InReviewState,CompletedState),每个状态类实现对应的操作逻辑,并且可以根据状态转移规则切换状态。这样,工作流系统在处理不同状态时,可以更加清晰和模块化。

2. 订单处理系统

场景描述: 电商平台中的订单处理通常涉及多个状态,如"新订单"、"已发货"、"已完成"、"已取消"等。每个状态下的操作(如发货、取消订单)都是不同的。

应用示例: 使用状态模式来管理订单的状态。每个状态(例如NewOrderState,ShippedState,CompletedState,CancelledState)会实现不同的操作方法,并且通过上下文类来维护和切换这些状态。

3. 游戏开发

场景描述: 在游戏中,角色或对象通常有多个状态,如"行走"、"跳跃"、"攻击"、"休息"等。每个状态下的行为和属性是不同的。

应用示例: 使用状态模式为角色定义不同的状态类(例如WalkingState,JumpingState,AttackingState,RestState),并在上下文类中管理角色的状态。这使得状态转移和行为变化变得更加直观和易于维护。

4. UI组件

场景描述: 用户界面(UI)组件如按钮可能有不同的状态,如"正常"、"悬停"、"按下"、"禁用"等,每种状态下的外观和行为都可能不同。

应用示例: 使用状态模式来管理按钮的不同状态。每个状态类(如NormalState,HoverState,PressState,DisableState)定义相应的绘制和交互逻辑,并在按钮类中根据用户操作切换状态。

5. 电梯控制系统

场景描述: 电梯有不同的状态,如"空闲"、"上升中"、"下降中"、"门开"等。每个状态下电梯的行为是不同的。

应用示例: 使用状态模式来管理电梯的状态。定义不同的状态类(如IdleState,MovingUpState,MovingDownState,DoorOpenState),每个状态类负责处理相应的行为,并通过上下文类来切换电梯的状态。

6. 网络连接管理

场景描述: 网络连接可能有多个状态,如"连接中"、"连接成功"、"连接失败"、"断开连接"等。不同的状态下需要执行不同的操作或处理不同的事件。

应用示例: 使用状态模式来管理网络连接的状态。每个状态类(如ConectingState,ConectedState,FailedState,DisconnectedState)实现不同的处理逻辑,并在网络连接管理类中根据实际情况切换状态。

四、总结

状态模式通过将不同状态的行为封装到独立的状态类中,提供了一种清晰的方式来管理对象在不同状态下的行为。虽然它可能引入一些额外的复杂性,但在需要管理多个状态和状态转换时,它能显著提高代码的可维护性和灵活性。

相关推荐
雨中飘荡的记忆18 分钟前
深入理解设计模式之单例模式
java·设计模式
闻缺陷则喜何志丹40 分钟前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
BestOrNothing_20151 小时前
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)
c++·函数重载·运算符重载·operator·前置后置++·重载与重写
2501_941144421 小时前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码1 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
8***29312 小时前
能懂!基于Springboot的用户增删查改(三层设计模式)
spring boot·后端·设计模式
charlie1145141912 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
Cx330❀2 小时前
C++ STL set 完全指南:从基础用法到实战技巧
开发语言·数据结构·c++·算法·leetcode·面试
zmzb01032 小时前
C++课后习题训练记录Day33
开发语言·c++
Want5953 小时前
C/C++贪吃蛇小游戏
c语言·开发语言·c++