状态模式和策略模式对比

devtools/2024/9/25 21:25:10/

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

状态模式

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

请添加图片描述

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

策略模式

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

请添加图片描述

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

状态模式策略模式的对比

无论状态模式,还是策略模式,都是创建型模式。其主要职责都是将变化的行为封装起来,使得程序更加灵活和可维护。状态模式主要用于处理一个对象在其内部状态改变时,需要改变其行为的情况。状态模式通过将状态相关的代码抽取到状态类中,实现了状态与状态上下文的解耦。在对象有多个状态,且状态之间存在复杂的转换逻辑时,状态模式可以简化代码和提高可维护性。而策略模式通过定义一组可相互替换的算法(算法簇),实现将算法独立于使用它的用户而变化。从功能上来说,状态模式和策略完全是两个完全不相似的设计模式
接下来重点分析状态模式策略模式的结构。从类图结构上看,策略模式状态模式很相似。都有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.ppmy.cn/devtools/21595.html

相关文章

网络安全-Diffie Hellman密钥协商

密钥协商是保密通信双方(或更多方)通过公开信道来共同形成密钥的过程。一个密钥协商方案中,密钥的值是某个函数值,其输入量由两个成员(或更多方)来提供。密钥协商的记过是参与协商的双方(或更多…

MySQL的数据备份和恢复

📟作者主页:慢热的陕西人 🌴专栏链接:MySQL 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 本博客主要内容涉及到mysql数据库的备份和恢复 文章目录 MySQL的数据备…

【MyBatis】初步解析MyBatis:实现数据库交互与关系映射的全面指南

💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【MyBatis】初步解析MyBatis:实现数据库交互与关系映射的全面指南 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 前言什么是MyBatis?一. MyBa…

UML 的工厂方法设计模式 策略设计模式 抽象工厂设计模式 观察者设计模式

UML 的工厂方法设计模式 UML 的工厂方法设计模式是一种创建型设计模式,它通过定义一个创建对象的接口,但将具体的对象创建延迟到子类中。这样可以让子类决定实例化哪个类。该模式提供了一种创建对象的灵活方式,同时也隐藏了对象的具体实现细…

【C++】学习笔记——内存管理

文章目录 二、类和对象20. 友元1. 友元函数2.友元类 21. 内部类22. 匿名对象23. 拷贝对象时的一些编译器优化 三、内存管理1. C/C内存分布2. C语言中动态内存管理方式:malloc/calloc/realloc/free3. C内存管理方式 未完待续 二、类和对象 20. 友元 1. 友元函数 我…

解锁无限资源:用爬虫玩转石墨文档

石墨文档作为一款在线协作编辑工具,汇集了大量的优质文档资源。然而,有时我们需要更多、更广泛的资源,这时候,利用爬虫技术就能轻松获取到我们需要的文档。本文将详细介绍如何利用爬虫玩转石墨文档,解锁无限资源的奥秘…

探索Vue 3 reactive()原理及其实现步骤

探索Vue 3 reactive()原理及其实现步骤 引言 Vue 3中引入的Composition API,以其强大的灵活性和可组合性,彻底改变了Vue应用的开发方式。在这场革新中,reactive()函数扮演了核心角色,它使得开发者能够轻松创建响应式对象&#x…

互联网大厂ssp面经,数据结构part3

1. 哈希表的原理是什么?如何解决哈希碰撞问题? a. 原理:通过哈希函数将每个键映射到一个唯一的索引位置,然后将值存储在对应索引位置的存储桶中。 b. 关键:将不同的键映射到不同的索引位置,以实现快速的插…