状态模式和策略模式对比

状态模式和策略模式都是行为型设计模式,它们的主要目标都是将变化的行为封装起来,使得程序更加灵活和可维护。之所以将状态模式和策略模式进行比较,主要是因为两个设计模式的类图相似度较高。但是,从状态模式和策略模式的应用场景来说,两个模式存在显著的差异。接下来将一步步说明。

状态模式

状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,使其看起来修改了自身所属的类。状态模式的本质是将状态对象化处理。其类图表示如下:

请添加图片描述

状态模式主要适用于状态数量非常多且状态相关的代码会频繁变更的话,或代码中包含大量与对象状态有关的条件语句,或基于条件的状态机转换中存在许多重复代码等场景。通过将状态相关的代码抽取到状态类中,实现了状态与状态上下文的解耦。这样,就可在不修改已有状态类和上下文的前提下,引入新状态,这符合面向对象的开闭原则。但是,状态模式因为将状态对象化处理,也会带来代码复杂度上升的问题。如果只有很少的几个状态,或者状态很少发生变化,则不建议使用状态模式。此外,虽然引入新状态可以不用修改已有状态类和上下文,但是增加新的状态类需要修改那些负责状态转换的源代码,这无疑违背“开闭”原则。

策略模式

策略模式也是一种行为设计模式,策略模式通过定义一组可相互替换的算法,实现将算法独立于使用它的用户而变化。简单来说,就是定义一系列算法,然后将每一个算法封装起来,并使它们可相互替换。其类图表示如下:

请添加图片描述

从策略模式的类图可知,策略模式就是抽象了算法,并通过策略上下文完成了具体算法策略的选择。
策略模式适用于一个行为有多种实现、或为了消除复杂的条件运算符(如多重的条件选择语句),实现同一算法在不同变体中切换等场景。策略模式将算法的实现独立出来,实现了在不修改原有系统的基础上选择算法或行为,这符合开闭原则。此外,策略模式还可消除多重条件语句,降低代码复杂度。与其他设计模式一样,策略模式因为需要引入新的算法接口和实现,会带来代码复杂度上升的问题。策略模式虽然可以在不修改原有系统的基础上选择算法或行为,但是新增一个算法实现,仍需要修改策略上下文。而且,对于条件语句少的场景或算法极少变化的场景下,没有必要引入策略模式。

状态模式和策略模式的对比

无论状态模式,还是策略模式,都是创建型模式。其主要职责都是将变化的行为封装起来,使得程序更加灵活和可维护。状态模式主要用于处理一个对象在其内部状态改变时,需要改变其行为的情况。状态模式通过将状态相关的代码抽取到状态类中,实现了状态与状态上下文的解耦。在对象有多个状态,且状态之间存在复杂的转换逻辑时,状态模式可以简化代码和提高可维护性。而策略模式通过定义一组可相互替换的算法(算法簇),实现将算法独立于使用它的用户而变化。从功能上来说,状态模式和策略完全是两个完全不相似的设计模式。
接下来重点分析状态模式和策略模式的结构。从类图结构上看,策略模式和状态模式很相似。都有Context,且这个Context都依赖抽象的状态或策略。且抽象的状态或策略都有多种实现。但是,两个设计模式也仅仅是类图相似,其职责完全不同。在状态模式中,StateContext保存了State对象(具体状态对象)的引用,并将所有与该状态相关的工作委派给它。而在策略模式中,StrategyContext维护指向Strategy对象(具体策略)的引用,且仅通过策略接口与该对象进行交流。在状态模式中,多个State对象可能存在交互(如从状态A切换到状态B)。而在策略模式中,每个Strategy对象都不需要感知其他Strategy对象的存在(每个Strategy子类都是行为的封装)。策略模式偏重于可替换的算法以及这些算法在对应的Context中的正确调用,而状态模式则偏重于各状态自身的逻辑运行以及各个状态间的切换和初始化。
对比发现,虽然状态模式和策略模式虽然都是行为型设计模式,且类图相似度极高,但是两个策略无论在使用场景、还是对象的职责上,都存在明显的差异,在选用时很容易区分。

参考

https://yiyan.baidu.com/ 文心一言
《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redisson分布式锁,重试锁和锁续命的原理

RedissonLock 锁重试原理 tryLock有三个三个参数,第一个是等待时间,第二个是锁失效后自动释放的时间,不填默认为-1,第三个是时间单位; 当设置了第一个参数,那这个锁就成了可重试锁;获取锁失败后&#xff0c…

大数据分析与内存计算学习笔记

一、Scala编程初级实践 1.计算级数: 请用脚本的方式编程计算并输出下列级数的前n项之和Sn,直到Sn刚好大于或等于q为止,其中q为大于0的整数,其值通过键盘输入。(不使用脚本执行方式可写Java代码转换成Scala代码执行&a…

【R语言数据分析】数据类型与数据结构

R的数据类型有数值型num,字符型chr,逻辑型logi等等。 R最常处理的数据结构是:向量,数据框,矩阵,列表。 向量有数值型向量,字符型向量,逻辑型向量等,字符型向量就是反应…

普通屏幕已过时?裸眼3D屏幕显示效果更胜一筹!

随着多媒体技术的迅猛进步,我们日常生活中的内容展现方式,已经经历了前所未有的变革。在这其中,裸眼3D屏幕的应用,无疑是最为引人注目的亮点,它相较于传统屏幕,在显示效果上展现出了鲜明的优势,…

ComfyUI最新InsightFaceLoader节点无法安装的问题

最近更新一个工作流。里面有一些爆红节点,很正常的想到去Manager安装,于是乎开启Clash猫远程安装。装完了还是有一些报错,InsightFaceLoader也无法安装,很奇怪,很常用的节点啊。 一查是ComfyUI_IPAdapter_plus模块的。…

C#知识|汇总方法重载与静态方法应用技巧

哈喽,你好,我是雷工! 今天学习C#方法重载与静态方法应用技巧的相关内容。 01 方法重载有什么好处? 1.1、可以有效的减少类的对外接口(只显示一个方法比较简洁),从而降低类的复杂度。 1.2、方便…

java实现模板填充word,word转pdf,pdf转图片

Java实现Word转PDF及PDF转图片 在日常开发中,我们经常需要将文件操作,比如: 根据模板填充wordword文档中插入图片Word文档转换为PDF格式将PDF文件转换为图片。 这些转换可以帮助我们在不同的场景下展示或处理文档内容。下面,我将…

鹏哥C语言复习——字符函数与字符串函数

目录 一.字符函数 1.字符分类函数 2.字符转换函数 二.基础字符串函数 1.strlen函数 2.strcpy函数 3.strcat函数 4.strcmp函数 三.基础字符串函数优化 1.strncpy函数 2.strncat函数 3.strncmp函数 四.进阶字符串函数 1.strstr函数 2.strtok函数 3.strerror函数 一…

python实现的基于单向循环链表插入排序

相比于定义一个循环双向链表来实现插入排序来说,下面的实现采用一个单向循环链表来实现,并且不需要定义一个单向循环链表类,而是把一个list(数组/顺序表)当成单向循环链表来用,list的元素是一个包含两个元素…

Linux migrate_type初步探索

1、基础知识 我们都知道Linux内存组织管理结构架构,顶层是struct pglist_data,然后再到struct zone,最后是struct page。大概的管理结构是这样的: 根据物理内存的地址范围可划分不同的zone,每个zone里的内存由buddy…

赋能智慧校园!A3D数字孪生可视化,轻量又高效!

放假之后,学生们会逐步返学,大量人员出入校园,安全更是不容忽视,如何在短时间内对大批人员及设施进行智能监管?数字化转型是关键手段,我们可以融合线上线下数据,搭建3D立体的智慧校园&#xff0…

latex+vscode一直报错,配置文件json和环境变脸配置

1、json配置文件 {"latex-workshop.latex.tools": [{"name": "xelatex","command": "xelatex","args": ["-synctex1","-interactionnonstopmode","-file-line-error","%DOCF…

Hive主要介绍

Hive介绍 hive是基于 Hadoop平台操作 HDFS 文件的插件工具 可以将结构化的数据文件映射为一张数据库表 可以将 HQL 语句转换为 MapReduce 程序 1.hive 是由驱动器组成,驱动器主要由4个组件组成(解析器、编译器、优化器、执行器) 2.hive本身不…

访问jwt生成token404解决方法

背景: 1.在部署新的阿里云环境后发现调用jwt生成token的方法404,前端除了404,台不报任何错误 在本地好用,在老的阿里云环境好用, 2.缩短生成私钥的参数报错,以为私钥太长改了tomcat参数也无效&#xff0…

《MySQL对库的基本操作》

文章目录 一、查看数据库列表查看数据库中的所有表想知道当前处于哪个数据库里 二、创建一个数据库三、删除一个数据库知道两个集1.字符集2.校验集修改数据库的字符集和编码集 不同的校验码对数据库的影响四、数据库的备份与恢复注意事项:备份数据库中的表 总结 一、…

算法训练营第十三天 | LeetCode 239 滑动窗口最大值、LeetCode 347 前K个高频元素

LeetCode 239 滑动窗口最大值 本体初始思路是这样的,首先看下给定数组长度和维持一个滑动窗口所需要花费的时间复杂度之间的关系。初步判断是还行的,当然后面被样例打脸了。需要更新成优先队列的解法。原本的解法能通过37/51和46/51的测试用例。但这还不…

【Kotlin】Channel简介

1 前言 Channel 是一个并发安全的阻塞队列,可以通过 send 函数往队列中塞入数据,通过 receive 函数从队列中取出数据。 当队列被塞满时,send 函数将被挂起,直到队列有空闲缓存;当队列空闲时,receive 函数将…

python可视化学习笔记折线图问题-起始点问题

问题描述: 起始点的位置不对 from pyecharts.charts import Line import pyecharts.options as opts # 示例数据 x_data [1,2,3,4,5] y_data [1, 2, 3, 4, 5] # 创建 Line 图表 line Line() line.add_xaxis(x_data) line.add_yaxis("test", y_data) li…

基于Hyperf的CMS,企业官网通用php-swoole后台管理系统

2023年9月11日10:47:00 仓库地址: https://gitee.com/open-php/zx-hyperf-cms CMS,企业官网通用PHP后台管理系统 框架介绍 hyperf SCUI 后端开发组件 php 8.1 hyperf 3.1 数据库 sql(使用最新日期文件) hyperf\doc\sql_bak mysql 8. 系统默认账号…

STM32 F103C8T6学习笔记17:类IIC通信—MLX90614红外非接触温度计

今日学习配置MLX90614红外非接触温度计 与 STM32 F103C8T6 单片机的通信 文章提供测试代码讲解、完整工程下载、测试效果图 本文需要用到的大概基础知识:1.3寸OLED配置通信显示、IIC通信、 定时器配置使用 这里就只贴出我的 OLED驱动方面的网址链接了&#xff1a…