15.状态模式(State)

news2025/1/15 16:31:51

UML

意图:允许一个对象在其内部状态改变时改变它的行为,使得对象看起来好像修改了它的类型一样。

在这里插入图片描述

Context:定义客户感兴趣的接口;
维护一个ConcreteState子类的实例,这个实例定义当前的状态。
State:定义一个接口来封装Context的与特定状态相关的行为。
ConcreteState:每个ConcreteState实现一个与Context的一个状态相关的行为。

状态模式是用途非常广泛的模式,所有使用到有限状态机(FSM)的地方都可以使用该模式。当然,如果不使用状态模式的话,switch/case语句也可以胜任简单的状态机,但对于大型的状态机具有大量的状态和事件,维护冗长、嵌套的switch/case语句是非常困难和容易出错的,而且switch/case语句通常都没有很好地分离状态机的逻辑和要执行的操作。另外一种选择状态转移表(WIS20中采用),它更容易维护,如果要增加新的状态转移,只要向表中增加一行就可以了,而且可以在运行时动态改变状态机的逻辑,还可以创建多个不同的状态转移表,在运行时动态地选择解释执行哪一个,但缺点是要编写大量的代码去支持状态转移表,而且需要查询和解释执行,速度较慢

状态模式是最灵活、最高效的选择,因为它彻底分离了状态机的逻辑和动作行为,二者可以独立变化、互不影响,而且容易扩展,同时效率很高。当然,它也有缺点,就是编写State的派生类是一项乏味的工作,同时状态逻辑分散,无法在一个地方看到整个状态机的逻辑。为了克服这两个缺点,可以用一个文本描述状态转移表,然后用适当的Software Factory工具把它变成状态模式所必需的类的代码。

GUI是典型的状态应用。哪些菜单项和按钮是Disabled,哪个窗口应该激活,焦点应放在哪里,等等,都和状态有关。如果不把这些要素组织成为一个单一的、集中的状态机控制结构,那将是一场噩梦。

代码

#include <iostream>
#include <list>
using namespace std;
 
 
class State;
class ConcreteStateA;
class ConcreteStateB;
 
class Context
{
public:
    State *state;
    Context(State *_state):state(_state){}
    void Request();
};
 
class State
{
public:
    string name;
    virtual void Handle(Context *c) = 0;
    virtual ~State(){
        cout << "delete :" << this->name << endl;
    };
};
 
class ConcreteStateA:public State
{
public:
    ConcreteStateA(){
        name = "状态A";
    }
    virtual void Handle(Context *c);
};
 
class ConcreteStateB:public State
{
public:
    ConcreteStateB(){
        name = "状态B";
    }
    virtual void Handle(Context *c);
};
void ConcreteStateA::Handle(Context *c){
    delete c->state;
    c->state = new ConcreteStateB();
}
void ConcreteStateB::Handle(Context *c){
    delete c->state;
    c->state = new ConcreteStateA();
}
void Context::Request(){
    cout << "当前状态:" << state->name << endl;
    this->state->Handle(this);
    cout << "切换后状态:" << state->name << endl << endl;
}
int main(void)
{
    Context *c = new Context(new ConcreteStateA());
    c->Request();
    c->Request();
    c->Request();
    c->Request();
    return 0;
}

运行结果

当前状态:状态A
delete :状态A
切换后状态:状态B
 
当前状态:状态B
delete :状态B
切换后状态:状态A
 
当前状态:状态A
delete :状态A
切换后状态:状态B
 
当前状态:状态B
delete :状态B
切换后状态:状态A

参考:https://lkmao.blog.csdn.net/article/details/129017715

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA原理与结构(0)——目录与传送门

一、 简介 FPGA的设计和软件设计不同&#xff0c;我们所设计的RTL代码最终还是要落实到硬件底层来进行实例化&#xff0c;因此理解硬件底层的内容是很有意义的。 二、可编程逻辑块CLB 可配置逻辑块CLB&#xff08;Configurable Logic Block&#xff09;是xilinx系类FPGA的基本…

极验率先推出一键认证安全版,供客户自主免费升级,规避日常运营中的风险盲区

2017年6月1日&#xff0c;互联网服务开始响应《中华人民共和国网络安全法》的要求实施账号实名认证。由此&#xff0c;手机号码成为网络世界最主要的“身份证”&#xff0c;也让本机号码一键认证成为可能。其中&#xff0c;极验是最早的直连三大运营商的五家供应商之一&#xf…

Linux内核分析:输入输出,字符与块设备 31-35

CPU 并不直接和设备打交道,它们中间有一个叫作设备控制器(Device Control Unit)的组件,例如硬盘有磁盘控制器、USB 有 USB 控制器、显示器有视频控制器等。这些控制器就像代理商一样,它们知道如何应对硬盘、鼠标、键盘、显示器的行为。 输入输出设备我们大致可以分为两类…

“深入理解事件处理器、表单综合案例和组件通信“

目录 引言1. Vue的事件处理器2. Vue的表单综合案例3. Vue的组件通信总结 引言 Vue.js是一款流行的JavaScript框架&#xff0c;广泛应用于现代Web开发中。在Vue的世界里&#xff0c;事件处理器、表单综合案例和组件通信是三个重要的主题。本文将深入探讨这些主题&#xff0c;并…

二十二、MySQL联合查询

1、基础概念 &#xff08;1&#xff09;语法&#xff1a; select …… from …… union [all] select …… from …… &#xff08;2&#xff09;理解&#xff1a; 所谓的联合查询&#xff0c;就是对多个条件查询结果进行联合处理&#xff0c;取其并集。 2、实际操作 &…

AI写作生成器-人工智能技术的工具

众所周知&#xff0c;写作是一项需要时间、思考和创造力的工作。传统的写作过程可能需要作者长时间的积累、思考和修改&#xff0c;才能产生一篇优质的文章。随着AI写作生成器的出现&#xff0c;这一传统写作模式正经历着巨大的改变。 AI写作生成器是一类基于人工智能技术的工…

SpringBoot对Filter过滤器中的异常进行全局处理

前言 今天处理拦截器中的异常时&#xff0c;遇到这样一个问题&#xff0c;我们希望在过滤器中对用户的请求进行判断&#xff0c;如果不符合要求直接抛出异常并在前端展示。但是如果我们直接在过滤器中throw一个异常时&#xff0c;尽管我们使用ControllerAdvice和 ExceptionHan…

一对多映射处理

8.3.1 、collection /** * 根据部门id查新部门以及部门中的员工信息 * param did * return */ Dept getDeptEmpByDid(Param("did") int did);<resultMap id"deptEmpMap" type"Dept"> <id property"did" column"did&quo…

Java21 LTS版本

一、前言 除了众所周知的 JEP 之外&#xff0c;Java 21 还有更多内容。首先请确认 java 版本&#xff1a; $ java -version openjdk version "21" 2023-09-19 OpenJDK Runtime Environment (build 2135-2513) OpenJDK 64-Bit Server VM (build 2135-2513, mixed mo…

Shiro 整合 Web

文章目录 Shiro的Web流程Shiro整合SSMShiro整合SpringBootShiro授权方式过滤器链自定义过滤器注解记住我 Shiro的Web流程 Shiro整合SSM 准备SSM的配置准备经典五张表&#xff08;见Shiro基本使用&#xff09;&#xff0c;完成测试准备Shiro的配置 核心过滤器 <!-- 配置S…

Git学习笔记4

GitHub是目前最火的开源项目代码托管平台。它是基于web的Git仓库&#xff0c;提供公有仓库和私有仓库&#xff0c;但私有仓库是需要付费的。 到Github上找类似的项目软件。 GitLab可以创建免费的私有仓库。 GitLab是利用 Ruby开发的一个开源的版本管理系统&#xff0c;实现一个…

ResFields: 一种即插即用的MLP增容工具

ResFields: 一种即插即用的MLP增容工具 目录 概述 RESFIELDS 理论简介 实验(部分) 2D VIDEO APPROXIMATION1 TEMPORAL NEURAL RADIANCE FIELDS (NERF) 消融实验 环境配置 概述 论文名称: RESFIELDS: RESIDUAL NEURAL FIELDS FOR SPATIOTEMPORAL SIGNALS 作者单位…

基于Yolov8的野外烟雾检测(2):多维协作注意模块MCA,效果秒杀ECA、SRM、CBAM等 | 2023.9最新发布

目录 1.Yolov8介绍 2.野外火灾烟雾数据集介绍 3.MCA介绍 4.训练结果分析 5.系列篇 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前…

Docker 应用部署

Docker 应用部署 一、部署MySQL 搜索MySQL镜像 拉取MySQL镜像 docker pull mysql:8.0创建容器&#xff0c;设置端口映射&#xff0c;目录映射 # 在root/home/mysql目录下创建MySQL目录用于存储MySQL数据信息 mkdir /root/home/mysql cd /root/home/mysql创建并运行 # 330…

video属性练习,手写controls

<video src"../xxx.mp4"></video><div class"controls"><button id"btnPlay">播放/暂停</button></div><div class"controls" id"progress">进度&#xff1a;<input type&quo…

编译chromium总结

文章目录 一、官方文档二、DEPOT_TOOLS_UPDATE三、少修改subprocess.py里的编码四、运行截图 之前在ubuntu18编译过&#xff0c;这次换win11试一试&#xff0c;成功后我又删了一次&#xff0c;再次编译发现了之前没注意到的点。下面是一些重点和我的实践。 一、官方文档 https…

【MT7628AN】IOT | MT7628AN OpenWRT开发与学习

IOT | MT7628AN OpenWRT开发与学习 时间:2023-06-21 文章目录 `IOT` | `MT7628AN` `OpenWRT`[开发与学习](https://blog.csdn.net/I_feige/article/details/132911634?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132911634…

Python练习之选择与循环

目录 1、编写程序&#xff0c;运行后用户输入4位整数作为年份&#xff0c;判断其是否为闰年。提示&#xff1a;如果年份能被400整除&#xff0c;则为闰年&#xff1b;如果年份能被4整除但不能被100整除也为闰年。2、编写程序&#xff0c;用户从键盘输入小于 1000 的整数&#x…

链表oj题1(Leetcode)——移除链表元素,反转链表,链表的中间节点,

链表OJ 一&#xff0c;移除链表元素1.1分析1.2代码 二&#xff0c;找到链表的中间节点2.1分析2.2代码 三&#xff0c;反转链表3.1分析3.2代码 四&#xff0c;找到链表中倒数第k个节点4.1分析4.2代码 一&#xff0c;移除链表元素 移除链表元素 1.1分析 这里的删除要分成两种…

视频监控系统/视频汇聚平台EasyCVR平台页面展示优化

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…