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

【状态机实现】前置——设计模式中的孪生兄弟(状态模式和策略模式)

什么是行为型设计模式?
一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

一、状态模式

状态模式(State Pattern)是一种行为型设计模式,允许一个对象在其内部状态改变时改变其行为。这种模式通过将每个状态封装为一个单独的类来实现状态的转换。
在这里插入图片描述
1.1.状态模式用途:
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

1.2.为何需要状态模式:
封装状态转换:状态模式将所有与特定状态相关的行为封装在单个状态对象中,易于管理和修改。
简化条件逻辑:避免使用大量的条件语句来处理状态转换逻辑,使代码更加清晰。
提高可扩展性:新增状态时,只需添加新的状态类而无需修改现有代码,遵循开闭原则。

1.3.状态模式的组成:
上下文(Context)
定义:上下文持有一个状态对象的引用,定义了客户程序与状态对象交互的接口。
职责:维护当前状态,根据当前状态调用相应的行为。

状态接口(State)
定义:状态接口定义了一个或多个方法,用于封装与特定状态相关的行为。
职责:作为所有具体状态类的共同接口。

具体状态(Concrete State)
定义:具体状态类实现状态接口,并根据状态的具体行为来实现这些方法。
职责:定义在特定状态下对象的行为。

角色之间的交互
状态维护:上下文通过持有状态对象的引用来维护当前状态。
状态转换:当对象的状态需要改变时,上下文会替换状态对象,从而改变行为。
行为执行:上下文通过委托给当前状态对象来执行相关的行为。

二、策略模式

一种行为型设计模式,它定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换或独立于使用它的客户而变化。

2.1.业务场景
假设有这样的业务场景,大数据系统把文件推送过来,根据不同类型采取不同的解析方式。多数的小伙伴就会写出以下的代码:

if(type=="A"){//按照A格式解析
}else if(type=="B"){//按B格式解析
}else{//按照默认格式解析
}

就是以上代码,违背了面向对象编程的开闭原则以及单一原则。
● 开闭原则(对于扩展是开放的,但是对于修改是封闭的)
● 单一原则(规定一个类应该只有一个发生变化的原因)

2.2.适用场景
在一个系统里面有许多类,它们之间的区别仅在于它们的行为,使用策略模式可以动态地让一个对象在许多行为中选择一种行为;一个系统需要动态地在几种算法中选择一种; 避免使用难以维护的多重条件选择语句;希望在具体策略类中封装 算法和与相关的数据结构。例如:
● 算法动态切换(如支付方式、排序策略)。
● 避免多重条件判断(将条件逻辑封装为具体策略类)。

2.3.策略模式的结构
1.抽象策略类 Strategy Interface):定义所有支持的策略或行为的公共接口。这是一个抽象类或接口,通常只有一个方法,用于执行算法。
2.具体策略类(Concrete Strategy Classes):实现了策略接口的类,每个类都代表一种具体的算法或行为。
3.环境类(Context):又称上下文,上下文包含
● 策略接口声明的成员变量
● 注入构造方法为该成员变量赋值
● 持有一个策略类的引用,最终给客户端调用。该方法通过接口变量调用对应的具体策略

三、区别

在行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们再次看看两者的简易通用类图,把两者放在一起比较一下,如图所示:

讲真,我觉得它们都差不多啊,好难区别啊!!!
不过,虽然讲不出来它们的区别是什么,但是有个例子可以很好的描述它们的区别

  • 状态模式:这个模式就好比员工申请离职单的流程,离职单到直接上级,这个状态就是直接上级批示,等直接上级审阅之后,通过了就到下一个状态。这一个个状态对应不同的处理,这是有顺序要求的。
  • 策略模式:这个模式好比于你假期要出国游玩,有日本、美国、新加坡等国家,你每到一个国家就执行不同的游玩策略,可以先去日本,也可以先去美国,没有顺序要求。

简单记:策略是选择,状态是流转

对比表格

维度策略模式 (Strategy Pattern)状态模式 (State Pattern)
意图封装和互换一系列算法,使算法独立于使用它的客户端而变化。允许一个对象在其内部状态改变时改变它的行为,对象看起来好像修改了它的类。
核心思想“选择”行为。客户端主动选择一个合适的策略来完成一项任务。“状态”驱动行为。对象的行为由当前状态决定,并且状态会根据规则自动转换。
上下文角色上下文对策略一无所知,它只是简单地调用策略对象的通用接口。上下文知道状态,并可能持有所有状态对象的引用,以便进行状态切换。
依赖关系策略之间通常彼此独立,不知道其他策略的存在。状态对象通常知道其他状态,并负责将自己切换到下一个状态(或由上下文根据状态对象的指示来切换)。
控制权客户端(调用者) 决定使用哪个策略。控制权在外部。状态转换的规则封装在状态类或上下文中。控制权在内部状态机里。
生命周期策略对象通常在需要时才被客户端创建和设置,之后可能被替换。它们是无状态的工具状态对象经常被共享和重用(通常实现为享元)。它们代表了一个状态,这个状态本身可能包含数据。
类比支付方式:出门购物,你可以主动选择用支付宝、信用卡还是现金。这些是策略。电风扇档位:你按一下按钮(触发事件),风扇从“关闭”状态切换到“一档”状态,再按一下切换到“二档”。档位(状态)决定了风速(行为),且切换是顺序的、有规则的。
http://www.dtcms.com/a/392426.html

相关文章:

  • 【LeetCode - 每日1题】设计路由器
  • springboot宠物领养救助平台的开发与设计(代码+数据库+LW)
  • CSS的三大特性
  • 实现excel的树形导出
  • 基于Matlab的GPS/北斗系统抗脉冲与窄带干扰算法研究及仿真验证
  • linux之负载均衡Nginx+多开Tomcat
  • 浏览器私有前缀、CSS3:2D转换、动画、3D转换
  • Redis核心面试知识点汇总
  • Java面试宝典:核心基础知识精讲
  • Python9-逻辑回归-决策树
  • 神经网络核心机制深度解析:链式法则驱动下的梯度流动与参数优化
  • Spring事务和事务传播机制(半)
  • 61.[前端开发-Vue3]Day03-购物车-v-model-组件化-Vue脚手架
  • Kafka学习笔记(p1-p14)
  • C++:四大智能指针
  • Roo Code 键盘导航与快捷键
  • SQL从入门到起飞:完整学习数据库与100+练习题
  • MyBatis 动态 SQL 详解:优雅处理复杂查询场景
  • 如何看待Qt中的QObject这个类
  • utf8mb4_bin 与 utf8mb4_generate_cli区别
  • CAN总线学习(一)CAN总线通讯&硬件电路
  • 13. LangChain4j + 加入检索增加生成 RAG(知识库)
  • TriggerRecovery
  • OpenAI 开源 GPT-oss 模型:从闭源到开源的模型架构创新之路
  • 微服务技术栈一文串讲
  • 从浅入深:自编码器(AE)与变分自编码器(VAE)的核心原理与Pytorch代码讲解
  • 低功耗超宽带收发器:DW1000设备驱动API指南
  • 2012/07 JLPT听力原文 问题四
  • Redis最佳实践——性能优化技巧之集群与分片
  • springboot的注解