当前位置: 首页 > news >正文

【设计模式】 状态模式

1、定义

1.1 标准定义

  其定义如下:
  Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为, 这个对象看起来像改变了其类。)

  状态模式的核心是封装, 状态的变更引起了行为的变更, 从外部看起来就好像这个对象对应的类发生了改变一样。

1.2 通用类图

  ● State——抽象状态角色
  接口或抽象类, 负责对象状态定义, 并且封装环境角色以实现状态切换。

  ● ConcreteState——具体状态角色
  每一个具体状态必须完成两个职责: 本状态的行为管理以及趋向状态处理, 通俗地说,就是本状态下要做的事情, 以及本状态如何过渡到其他状态。

  ● Context——环境角色
  定义客户端需要的接口, 并且负责具体状态的切换。

2、实现

2.1 类图

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

2.2 代码

#include <iostream>
using namespace std;

class Context;

class State
{
public:
   // 状态处理,此处可以选择是否切换到其他状态
virtual void Handle(Context *pContext) = 0; }; class ConcreteStateA : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateA."<<endl; } }; class ConcreteStateB : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateB."<<endl; } }; class Context { public: Context(State *pState) : m_pState(pState){} void Request() { if (m_pState) { m_pState->Handle(this); } } void ChangeState(State *pState) { m_pState = pState; } private: State *m_pState; }; int main() { State *pStateA = new ConcreteStateA(); State *pStateB = new ConcreteStateB(); Context *pContext = new Context(pStateA); pContext->Request(); pContext->ChangeState(pStateB); pContext->Request(); delete pContext; delete pStateB; delete pStateA; }

3、总结

3.1 优点

  ● 结构清晰
  避免了过多的switch...case或者if...else语句的使用, 避免了程序的复杂性,提高系统的可维护性。

  ● 遵循设计原则
  很好地体现了开闭原则和单一职责原则, 每个状态都是一个子类, 你要增加状态就要增加子类, 你要修改状态, 你只修改一个子类就可以了。

  ● 封装性非常好
  这也是状态模式的基本要求, 状态变换放置到类的内部来实现, 外部的调用不用知道类内部如何实现状态和行为的变换。

3.2 缺点

  状态模式既然有优点, 那当然有缺点了。 但只有一个缺点, 子类会太多, 也就是类膨胀。 

3.3 使用场景

  ● 行为随状态改变而改变的场景
  这也是状态模式的根本出发点, 例如权限设计, 人员的状态不同即使执行相同的行为结果也会不同, 在这种情况下需要考虑使用状态模式。

  ● 条件、 分支判断语句的替代者
  在程序中大量使用switch语句或者if判断语句会导致程序结构不清晰, 逻辑混乱, 使用状态模式可以很好地避免这一问题, 它通过扩展子类实现了条件的判断处理。

3.4 注意事项

  状态模式适用于当某个对象在它的状态发生改变时, 它的行为也随着发生比较大的变化, 也就是说在行为受状态约束的情况下可以使用状态模式, 而且使用时对象的状态最好不要超过5个。 

转载于:https://www.cnblogs.com/ChinaHook/p/7309215.html

相关文章:

  • IT技术人员转行大数据应该考虑哪些问题
  • 日常(关于机房卫生???)
  • 两矩阵相乘的秩的性质_浅析数学中的行列式与矩阵
  • (Python) SOAP Web Service (HTTP POST)
  • 苹果新款笔记本_谷歌发布售价99美元的新款Wi-Fi路由器(全文)_苹果 新款MacBook Pro 13英寸_笔记本新闻...
  • 使用IDEA从github中下载fastdfs-client-java
  • 苹果7手机严重卡顿_iPhone12 实测 5G 网络耗电更快丨苹果官方壳存在严重问题|iphone12|手机壳|续航|蜂窝...
  • [luoguP1666] 前缀单词(DP)
  • JZOJ 8.10 B组总结
  • android oboe 混音_Android之AppBarLayout实现悬停吸附伸缩效果
  • 第三百四十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—Requests请求和Response响应介绍...
  • 中台架构与实现:基于ddd和微服务 下载_提升建设效能 普元信息推出金融科技业务赋能中台软件...
  • 正则表达式和JavaScript中的RegExp对象
  • uka profinet gsd文件_西门子PLC和发那科机器人进行PROFINET通信
  • unsharp mark 算法_Google SEO-BERT算法更新
  • Create React App 使用
  • create-react-app项目添加less配置
  • interface和setter,getter
  • Java方法详解
  • JDK 6和JDK 7中的substring()方法
  • LintCode 31. partitionArray 数组划分
  • mysql 数据库四种事务隔离级别
  • session共享问题解决方案
  • Spring Boot快速入门(一):Hello Spring Boot
  • 构建二叉树进行数值数组的去重及优化
  • 近期前端发展计划
  • 聊聊hikari连接池的leakDetectionThreshold
  • 事件委托的小应用
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​iOS安全加固方法及实现
  • ​queue --- 一个同步的队列类​
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #QT(一种朴素的计算器实现方法)
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (四)图像的%2线性拉伸
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net Redis的秒杀Dome和异步执行
  • .NET基础篇——反射的奥妙
  • .NET实现之(自动更新)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @Autowired多个相同类型bean装配问题
  • @Bean有哪些属性
  • [ C++ ] STL---string类的模拟实现
  • [ 网络基础篇 ] MAP 迈普交换机常用命令详解
  • [20180224]expdp query 写法问题.txt
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [Android开源]EasySharedPreferences:优雅的进行SharedPreferences数据存储操作
  • [BZOJ 3680]吊打XXX(模拟退火)