【深入浅出设计模式--状态模式】

这篇具有很好参考价值的文章主要介绍了【深入浅出设计模式--状态模式】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

状态模式是一种行为设计模式,让你能在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类一样。其与有限状态机的概念紧密相关,如下所示:
【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式

二、问题

在实际设计编码UI界面的工作中,有很多人应该都遇到过类似这样的场景:当鼠标移动或者点击某个标签、按钮等组件时,对应组件上会根据鼠标的状态进行不同的响应,比如颜色大小的变化。如果状态有很多种,那我们就会在代码中添加许多条件判断(if-else、switch),有时候可能一条语句中的条件多达十来个,出现bug的时候调试起来相当恶心。基于这个问题,下面使用状态模式逐步解决。

三、解决方案

  1. 首先在上下文类Context中定义改变状态的接口changeState,并聚合了指向当前状态的IState对象指针,changeState的参数即为new生成的具体状态类NormorlState等,调用paintTags函数时会调用当前状态类的doPaint函数进行该状态下的绘制操作。
  2. 接口状态类IState中提供了doPaint纯虚函数,每个具体状态类会继承并重写doPaint,在doPaint中可以调用setHoverState等函数对Context类对象的成员变量进行修改,同步状态与操作。
  3. 为了对每个状态类对象进行复用,采用单例模式提供GetInstance函数供Context调用。
    类图如下:
    【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式
  4. 上面的类结构中,因为每个具体状态类都是单例模式,提供除了名字不同之外相同的代码块,因此会有许多重复代码,因此想到在接口状态类IStateBase和具体状态类之间插入一个单例模板类IStateTemplate专门提供静态GetInstance函数,然后每个具体状态类对其继承和模板特化,这样在具体状态类中只需要实现doPaint函数即可。
  5. 各类达到高度凝练与抽象,每一层只专注某一功能的效果。后续如果有新加入一种状态,只需要特化IStateTemplate,然后重写doPaint函数即可,其他状态的代码无需修改,减少大量条件判断的同时也降低了出错的概率。
    改进后的类图如下:
    【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式
  6. 该模式下各类之间交互的时序图如下:
    【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式
  7. Context类关键代码截图:
    【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式
  8. State相关类关键代码截图:
    【深入浅出设计模式--状态模式】,设计模式,c++,设计模式,状态模式,单例模式

四、 适用场景总结

  • 如果对象需要根据自身当前状态(成员变量值)进行不同行为,同时状态的数量非常多且与状态相关的代码会频繁变更的话,可使用状态模式。
  • 当相似状态和基于条件的状态机转换中存在许多重复代码时,可使用状态模式。
  • 如果状态机只有很少的几个状态,或者很少发生改变,那么应用该模式可能会显得小题大作。

五、后记

以上所有内容均为原创,代码已上传至gayhub:
https://github.com/gangster-puppy/Design-Pattern.git文章来源地址https://www.toymoban.com/news/detail-682709.html

到了这里,关于【深入浅出设计模式--状态模式】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解设计模式-创建型之单例模式

    如果有些数据在系统中应该且只能保存一份,那就应该设计为单例类。 如:配置类:在系统中,我们只有一个配置文件,当配置文件被加载到内存之后,应该被映射为一个唯一的【配置实例】,此时就可以使用单例,当然也可以不用。 全局计数器:我们使用一个全局的计数

    2024年02月12日
    浏览(16)
  • 【Java-10】深入浅出线程安全、死锁、状态、通讯、线程池

    线程安全 线程死锁 线程的状态 线程间通讯 线程池 1.1 线程安全产生的原因 多个线程在对共享数据进行读改写的时候,可能导致的数据错乱就是线程的安全问题了 问题出现的原因 : 多个线程在对共享数据进行读改写的时候,可能导致的数据错乱就是线程的安全问题了 1.2 线程

    2024年02月11日
    浏览(16)
  • 《深入浅出.NET框架设计与实现》笔记1——.NET CLI 概述

    .NET CLI(NET 命令行接口)工具是用于开发生成运行和发布.NET应用程序的跨平台工具链。 默认安装的命令有 1、基本命令 2、项目修改命令 3、高级命令 4、工具管理命令 工具三控制台应用程序,它们从NuGet包中安装并从命令提示符处进行调用。 CLI命令结构包 含驱动程序(“

    2024年04月22日
    浏览(12)
  • 【动手学深度学习】深入浅出深度学习之RMSProp算法的设计与实现

    目录 🌞一、实验目的 🌞二、实验准备 🌞三、实验内容 🌼1. 认识RMSProp算法 🌼2. 在optimizer_compare_naive.py中加入RMSProp 🌼3. 在optimizer_compare_mnist.py中加入RMSProp 🌼4. 问题的解决 🌞四、实验心得 深入学习RMSProp算法的原理和工作机制; 根据RMSProp算法的原理,设计并实现一个

    2024年04月10日
    浏览(16)
  • 懒汉单例设计模式与饿汉单例设计模式

    单例模式即一个类确保只有一个对象,主要用于避免浪费内存 1 .饿汉单例设计模式 :拿到对象时,对象就早已经创建好了 写法: 把类的构造器私有 在类中自己创建一个对象,并赋值到一个变量 定义一个静态方法,返回自己创建的这个对象 2. 懒汉单例设计模式 :第一次拿到对象时

    2024年02月21日
    浏览(16)
  • 【设计模式】单例设计模式

    目录 1、前言 2、基本语法 2.1、懒汉式单例 2.2、饿汉式单例 2.3、双重检验锁单例模式 2.4、静态内部类单例模式 2.5、枚举单例模式 2.6、ThreadLocal单例模式 2.7、注册单例模式 3、使用场景 4、使用示例 5、常见问题 5、总结 单例模式是一种设计模式,它确保一个类只能创建一个实

    2024年02月09日
    浏览(16)
  • 设计模式学习(一)单例模式补充——单例模式析构

    目录 前言 无法调用析构函数的原因 改进方法 内嵌回收类 智能指针 局部静态变量 参考文章 在《单例模式学习》中提到了,在单例对象是通过 new 动态分配在堆上的情况下,当程序退出时,不会通过C++的RAII机制自动调用其析构函数。本文讨论一下这种现象的原因以及

    2024年03月19日
    浏览(21)
  • 【设计模式】单例模式|最常用的设计模式

    单例模式是最常用的设计模式之一,虽然简单,但是还是有一些小坑点需要注意。本文介绍单例模式并使用go语言实现一遍单例模式。 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。 使用场景: 当类只能有一个实例而且可以从一个公开的众所周知的访

    2024年04月29日
    浏览(9)
  • 设计模式之单例设计模式

    就是一个类只允许创建一个对象,那么我们称该类为单例类,这种设计模式我们称为单例模式。 资源共享:有些类拥有共享的资源,例如数据库连接池、线程池、缓存等。使用单例模式确保只有一个实例,避免资源浪费和竞争条件。 线程安全:单例模式可以用来保证多线程

    2024年02月07日
    浏览(22)
  • 设计模式-单例模式

          单例模式(Singleton Pattern)是设计模式中最简单且最常用的一种创建型模式,其目的是保证一个类在整个系统中只存在一个实例,并提供全局访问点来获取这个唯一实例。这种模式主要适用于那些需要频繁实例化然后又希望避免因为多次实例化而消耗过多资源或产生副

    2024年01月17日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包