23种设计模式 之 State模式(状态模式)[C语言实现]

2023-11-11

一、概念定义

State模式:允许一个对象在其状态发生改变时,改变它的行为。

State模式和Strategy模式非常相似,需要说明的是两者的思想是一致的;只不过封装的对象不同:State模式封装的是不同的状态,而Strategy模式封装的是不同的算法。

State模式主要解决的问题是:在开发过程中,时常遇到需要根据不同的状态需要进行不同的处理操作的问题。大部分人采用的是switch-case语句进行处理的,这样会造成分支过多。State模式采用了对这些不同状态进行封装的方式处理这类问题,当状态发生变化时进行处理,再切换至另外一种状态,也就是说将状态切换的任务交给了状态类去负责。

二、模式结构图

图1 State模式结构图

三、场景设计

人的一生需经历:婴儿、青少年、中年、老年这几个阶段(状态),每个阶段对应的行为:婴儿->喝奶青少年->学习中->工作老年->退休。请用程序模拟这个过程的变化。

四、C语言实现

// 结构体定义

// 人生状态
typedef enum
{
    PSTATE_BABY,      // 婴儿
    PSTATE_YOUNG,     // 青少年
    PSTATE_MIDDLE,    // 中年
    PSTATE_OLD,       // 老年
    PSTATE_TOTAL      // 状态个数
}person_state_e;
// 人类:结构体
typedef struct
{
    ...
    int (*action)(void);     // 状态对应的行为
    ...
}person_t;

// 状态对应的行为

// 婴儿状态:喝奶, etc.
int drink(void)
{
    fprintf(stdout, "I am drinking milk!");
    return 0;
}
...
// 青少年状态:学习, etc.
int study(void)
{
    fprintf(stdout, "I am study!");
    return 0;
}
...
// 中年状态:工作, etc.
int work(void)
{
    fprintf(stdout, "I am working!");
    return 0;
}
...
// 老年状态:退休, etc.
int retire(void)
{
    fprintf(stdout, "I am have been retired!");
    return 0;
}
...

// 状态切换模块

 // 状态切换
int setstate(person_state_e state, person_t *person)
{
    switch(state)
    {
        case PSTATE_BABY:
        {
            ...
            person.action = drink;
            ...
            break;
        }
        case PSTATE_YOUNG:
        {
            ...
            person.action = study;
            ...
            break;
        }
        case PSTATE_MIDDLE:
        {
            ...
            person.action = work;
            ...
            break;
        }
        case PSTATE_OLD:
        {
            ...
            person.action = retrie;
            ...
            break;
        }
        default:
        {
            return -1;
        }
   }
   return 0;
}

//State模式的使用

int main(int argc, const char *argv[])
{
    person_t person;

    memset(person, 0, sizeof(person));

    setstate(PSTATE_BABY, &person);
    person.action();
    ...

    setstate(PSTATE_YOUNG, &person);
    person.action();
    ...

    setstate(PSTATE_MIDDLE, &person);
    person.action();
    ...

    setstate(PSTATE_OLD, &person);
    person.action();
    ...

    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

23种设计模式 之 State模式(状态模式)[C语言实现] 的相关文章

  • 经典面试题之new和malloc的区别

    new和malloc的区别是C C 一道经典的面试题 我也遇到过几次 回答的都不是很好 今天特意整理了一下 0 属性 new delete是C 关键字 需要编译器支持 malloc free是库函数 需要头文件支持 1 参数 使用new操作
  • Lua和C++交互总结(很详细)

    出处 http blog csdn net shun fzll article details 39120965 一 lua堆栈 要理解lua和c 交互 首先要理解lua堆栈 简单来说 Lua和C c 语言通信的主要方法是一个无处不在的虚拟
  • 程序员必知的23种设计模式之组合模式

    文章目录 1 模式引出 学校院系展示需求 1 1 传统方案 1 2 传统方案问题分析 2 组合模式基本介绍 2 1 方案修改 3 组合模式解决的问题 4 组合模式的注意事项和细节 1 模式引出 学校院系展示需求 编写程序展示一个学校院系结构
  • 设计模式之访问者模式

    访问者模式 把被操作的对象作为元素 可变可拓展的操作作为访问者 可以说访问者中有很多操作 然后访问者访问元素 对该元素进行操作 不同的访问者有不同的操作 案例 定义访问者接口 public interface UniversalVisito
  • 值得学习与推荐的c/c++框架和函数库

    这几天不上班 翻翻Evernote中记录的一些笔记 刚好有时间把记录的一些好玩链接转载一下 这篇文章里提到的很多库都用过 尤其是图像处理相关库 尤其是opencv及cximage 当时做图像算法时 很多算法就是从上面找来 然后自己修改的 比
  • DDD专家张逸:构建领域驱动设计知识体系

    张逸 读完需要 5分钟 速读仅需 2 分钟 领域驱动设计专家 曾就职于 ThoughtWorks 作为 Lead Consultant 为客户提供架构设计 大数据分析 持续交付 代码质量 敏捷管理等咨询服务 著译作包括 软件设计精要与模式
  • 为何在新建STM工程中全局声明两个宏

    在uVision中新建STM32工程后 需要从STM32标准库中拷贝标准外设驱动到自己的工程目录中 此时需要在工程设置 gt C C 选项卡下的Define文本框中键入这两个全局宏定义 STM32F40 41xxx USE STDPERIP
  • floor(),ceil()函数

    地板 天花板函数 均包含在math h中 意思分别为 返回不大于形参的最小整数和不小于形参的最大整数 include
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • JavaScript设计模式-02-单例模式

    Javascript 设计模式 02 单例模式 简介 单例就是保证一个类只有一个实例 实现的方法一般是先判断实例是否存在 如果存在直接返回 如果不存在就创建了再返回 确保了一个类只有一个实例对象 在JavaScript里 单例作为一个命名空
  • C++:指向类的成员的指针

    引 想必接触过C的朋友们对C语言中指针的概念已经有了深入的了解 如果初步进行了解的朋友可以看一下 C语言基础学习笔记 指针展开来讲的基本知识点包括 指针的概念 指针的定义和初始化及简单使用 指针函数和函数指针 有关指针函数和函数指针的内容上
  • 【C/C++】 - Linux下查找函数头文件 以及 man命令拓展

    背景 比如现在需要找C语言 sleep函数的头文件 使用man来查找 可以先man sleep 可以发现出来的默认是sleep 1 是一个User Commands 明显不是我们需要的 这里提示了 看sleep 3 那我们查看下sleep
  • 检查内存泄露

    自己编写的视频处理程序出现了一个问题 每帧的运行时间随着运行时间在不断增长 很大可能是出现了内存泄露 于是学习了一些查看内存泄露的方法 做了两种尝试 一是VS自带的DEBUG下的检测 view pl html view plain copy
  • 一个简单的参数帮助框架,c实现

    文章目录 具体实现如下 include
  • 设计模式(3)--对象结构(5)--外观

    1 意图 为子系统中的一组接口提供一个一致的界面 Facade模式定义了一个高层接口 这个接口使得 这一子系统更加容易使用 2 两种角色 子系统 Subsystem 外观 Facade 3 优点 3 1 对客户屏蔽了子系统组件 减少了客户处
  • C/C++编程:令人印象深刻的高级技巧案例

    C C 编程语言在软件开发领域有着悠久的历史 由于其高效 灵活和底层访问能力 至今仍然被广泛应用 本文将介绍一些在C C 编程中令人印象深刻的高级技巧 帮助读者提升编程水平 更加高效地使用这两种强大的编程语言 一 指针运算与内存管理 C C
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • C++ 字符串比较------strcmp函数和strncmp函数

    strcmp 函数原型 int strcmp const char str1 const char str2 功能 strcmp函数会按照字典顺序逐个比较两个字符串的字符 直到遇到不同的字符或者遇到字符串结束符 0 返回值 该函数返回值如下
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • 【设计模式之美】 SOLID 原则之五:依赖反转原则:将代码执行流程交给框架

    文章目录 一 控制反转 IOC 二 依赖注入 DI 三 依赖注入框架 DI Framework 四 依赖反转原则 DIP 一 控制反转 IOC 通过一个例子来看一下 什么是控制反转 public class UserServiceTest

随机推荐

  • 软件设计和硬件开发 部分学习网站

    1 单片机教程网 http www 51hei com 2 博客园 https www cnblogs com 3 各种程序语言基础知识 https www runoob com cprogramming c scope rules htm
  • Linux运维基础--常见命令

    Linux运维基础 常见命令 linux的发行版本介绍 Linux 内核 kernel 版本主要有 4 个系列 分别为 Linux kernel 2 2 Linux kernel 2 4 Linux kernel 2 6 Linux ker
  • 贪心——字典序最小问题

    https vjudge net problem POJ 3617 题目简单理解就是 给定长度为N的字符串为S 要构造一个长度为N的字符串T 起初 T 是一个空串 随后反复进行下列任意操作 从S的头部删除一个字符串 加到T的尾部 从S的尾部
  • 教与学(TlBO)算法路径规划应用

    是一种基于群体的启发式优化算法 不需要任何算法特定参数 这种方法模拟了传统的课堂教学过程 整个优化过程包括教师阶段和学习者阶段 在教师阶段 每个学生都向最优秀的个体进行学习 在学习阶段 每个学生都以随机的方式向其他学生学习
  • k8s--基础--23.3--认证-授权-准入控制--授权

    k8s 基础 23 3 认证 授权 准入控制 授权 1 介绍 Kubernetes的授权是基于插件形式的 其常用的授权插件有以下几种 1 Node 节点认证 2 ABAC 基于属性的访问控制 3 RBAC 基于角色的访问控制 4 Webho
  • 在IDEA中用jdbc技术通过配置文件连接mysql数据库连接池

    File gt project Structure gt Libraries gt 点 号 gt java gt 选择在电脑中下载druid 1 1 9 jar及以上版本的德鲁伊jar包和mysql connector java 8 0 0
  • MySQL-锁详解

    锁 锁是计算机协调多个进程或线程并发访问某一资源的机制 在数据库中 除传统的计算资源 如CPU RAM I O等 的争用以外 数据也是一种供许多用户共享的资源 如何保证数据并发访问的一致性 有效性是所有数据库必须解决的一个问题 锁冲突也是影
  • 算法刷题-双指针-反转链表

    反转链表的写法很简单 一些同学甚至可以背下来但过一阵就忘了该咋写 主要是因为没有理解真正的反转过程 206 反转链表 力扣题目链接 题意 反转一个单链表 示例 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL 输出 5 gt
  • fork() 函数

    请问下面的程序一共输出多少个 int main void int i for i 0 i lt 2 i fork printf return 0 答案 8 解析 参考文章 https coolshell cn articles 7965 h
  • Ubuntu 18.04 安装Tensorflow遇到的问题

    问题一 Tensorflow安装完成后测试时 出现libcublas so 9 0找不到问题 ImportError libcublas so 9 0 cannot open shared object file No such file
  • uni-app 数据上拉加载更多功能

    实现上拉加载更多 打开项目根目录中的 pages json 配置文件 为 subPackages 分包中的商品 goods list 页面配置上拉触底的距离 subPackages root subpkg pages path goods
  • 线程的同步和互斥

    线程的同步和互斥题目 题目 设计生产者与消费者模型 缓冲区是一个大小为10的环 每个生产者产生一个0 1000的随机整数 存放在环空位中 消费者从环中取数据 并输出 一个生产者或消费者对应一个线程 要避免 1 两个生产者同时向环的同一个位置
  • 两个数组找相同元素_leetcode数组--sort排序题目汇总

    概要 此类题目的特点是会遇到一些杂乱无序的数组 经过排序后 会更好处理 1051 高度检查器 学校在拍年度纪念照时 一般要求学生按照 非递减 的高度顺序排列 请你返回能让所有学生以 非递减 高度排列的最小必要移动人数 注意 当一组学生被选中
  • qrcode页面生成二维码

  • 2.使用服务端SDK

    使用服务端SDK 一 服务端SDK 1 简介 2 功能介绍 二 使用SDK 1 安装 2 初始化 3 创建测试类 三 创建测试用例 1 获取视频播放凭证 2 获取视频播放地址 一 服务端SDK 1 简介 sdk的方式将api进行了进一步的封
  • 人工智能的道德与伦理

    人工智能的道德与伦理 对人工智能的研究始于上世纪50年代 近几年 科学界和产业界对它的兴趣超越了以往 最近一年半来 谷歌收购了十几家机器人公司 并正在开发人工智能的一个图腾 无人驾驶汽车 去年 社交媒体脸谱成立了新的人工智能实验室 数据显示
  • 技术架构演进之路-Docker【二】

    docker 技术架构演进之路 了解每种技术架构以及如何演进的 熟悉Docker在架构中的核心作用 八大架构演进 一 单机架构 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img 9o2adujk 168437644
  • vue axios全攻略

    不再继续维护vue resource 并推荐大家使用 axios 开始 axios 被越来越多的人所了解 本来想在网上找找详细攻略 突然发现 axios 的官方文档本身就非常详细 有这个还要什么自行车 所以推荐大家学习这种库 最好详细阅读其
  • Linux应用编程

    进程控制 fork函数 函数说明 创建一个子进程 函数原型 pid t fork void 返回值 失败返回 1 成功返回 父进程返回子进程的ID 非负 子进程返回 0 pid t类型表示进程ID 但为了表示 1 它是有符号整型 0不是有效
  • 23种设计模式 之 State模式(状态模式)[C语言实现]

    一 概念定义 State模式 允许一个对象在其状态发生改变时 改变它的行为 State模式和Strategy模式非常相似 需要说明的是两者的思想是一致的 只不过封装的对象不同 State模式封装的是不同的状态 而Strategy模式封装的是