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

设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析

在这里插入图片描述

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,使得对象看起来好像修改了它的类。这种设计模式的核心思想是将对象的状态和行为封装成不同的状态类,通过状态对象的行为改变来避免大量的条件判断语句,从而提升代码的可扩展性和可维护性。

一、核心思想

状态模式的核心思想是将状态相关的行为抽取到独立的状态类中,使得增加新状态变得简单,且不影响其他状态。每个状态类都封装了对象在该状态下的行为,上下文类(Context)则维护一个状态对象,并在状态发生变化时改变其行为。

二、定义与结构

定义

状态模式(State Pattern)是行为设计模式的一种,它允许一个对象在其内部状态改变时改变它的行为。

结构

状态模式通常涉及以下几个关键组件:

  • State(状态):定义一个接口或抽象类,用于封装与上下文相关的行为。
  • ConcreteState(具体状态):实现状态接口或继承抽象状态类,具体定义每个状态下的行为。
  • Context(上下文):维护一个状态对象,并在状态发生变化时改变其行为。

三、角色

  • 环境角色(Context):也称为上下文,它定义了客户程序与状态对象交互的接口,并且保存了一个具体状态对象的引用。
  • 抽象状态(State):这是一个接口或抽象类,定义了所有具体状态所共有的一些行为。
  • 具体状态(Concrete States):这些是实现了抽象状态接口的具体类,每个类代表了一个状态,并且在该状态下定义了一些行为。

四、实现步骤及代码示例

以Java为例,状态模式的实现步骤通常包括:

  1. 定义状态接口:定义一个接口,用于封装与上下文相关的行为。
  2. 创建具体状态类:实现状态接口,具体定义每个状态下的行为。
  3. 定义上下文类:维护一个状态对象,并提供方法来切换状态和处理请求。

以下是一个简单的Java代码示例,用于展示状态模式的实现:

// 状态接口
interface State {void handle();
}// 具体状态类:待支付状态
class PendingState implements State {@Overridepublic void handle() {System.out.println("订单状态:待支付。请完成支付!");}
}// 具体状态类:已支付状态
class PaidState implements State {@Overridepublic void handle() {System.out.println("订单状态:已支付。订单处理中。");}
}// 具体状态类:已完成状态
class CompletedState implements State {@Overridepublic void handle() {System.out.println("订单状态:已完成。");}
}// 上下文类
class OrderContext {private State state;public OrderContext() {this.state = new PendingState(); // 初始状态为待支付}public void setState(State state) {this.state = state;}public void handleOrder() {state.handle();}
}// 客户端代码
public class Client {public static void main(String[] args) {OrderContext orderContext = new OrderContext();orderContext.handleOrder(); // 输出:订单状态:待支付。请完成支付!orderContext.setState(new PaidState());orderContext.handleOrder(); // 输出:订单状态:已支付。订单处理中。orderContext.setState(new CompletedState());orderContext.handleOrder(); // 输出:订单状态:已完成。}
}

五、常见技术框架应用

1、前端框架中状态模式的应用

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态发生改变时改变其行为。在前端框架中,状态模式的应用十分广泛,特别是在管理复杂的用户交互逻辑和页面状态时。以下是一些前端框架中应用状态模式的举例:

购物车状态管理

在电商网站的购物车页面中,商品的状态(如已添加、已删除、数量变化等)会影响购物车的整体行为和显示。使用状态模式,可以清晰地管理这些状态变化。

  • 状态定义:定义购物车状态的抽象类,如CartState,并为其定义添加商品、删除商品等抽象方法。
  • 具体状态类:创建具体的状态类,如EmptyCartState(空购物车状态)和NonEmptyCartState(非空购物车状态),在这些类中实现具体的行为。
  • 购物车类:在购物车类中,维护一个当前状态的引用,并根据状态的变化调用相应的方法。

例如,在购物车为空时,用户只能添加商品;在购物车非空时,用户可以查看商品列表、删除商品等。通过状态模式,可以轻松地管理这些状态变化,使代码更加清晰和可维护。

表单验证状态管理

在用户提交表单之前,需要对表单中的输入进行验证。使用状态模式,可以根据不同的验证状态(如有效、无效、必填项未填写等)来改变表单的行为。

  • 状态定义:定义表单验证状态的抽象类,如FormValidationState,并为其定义验证方法。
  • 具体状态类:创建具体的状态类,如ValidState(有效状态)、InvalidState(无效状态)和RequiredFieldMissingState(必填项未填写状态),在这些类中实现具体的验证逻辑。
  • 表单类:在表单类中,维护一个当前验证状态的引用,并根据状态的变化调用相应的方法来处理验证结果。

游戏状态管理

在游戏中,对象的状态可能会随着游戏的进程而发生变化,如角色的生命值、能量值、游戏阶段等。使用状态模式,可以轻松地管理这些状态变化。

  • 状态定义:定义游戏状态的抽象类,如GameState,并为其定义更新、渲染等方法。
  • 具体状态类:创建具体的状态类,如IdleState(空闲状态)、PlayingState(游戏进行状态)、GameOverState(游戏结束状态),在这些类中实现具体的游戏逻辑。
  • 游戏管理类:在游戏管理类中,维护一个当前游戏状态的引用,并根据状态的变化调用相应的方法来处理游戏逻辑。

UI组件状态管理

在前端开发中,一些UI组件(如按钮、输入框、下拉菜单等)的状态可能会随着用户的交互而发生变化。使用状态模式,可以清晰地管理这些状态变化。

  • 状态定义:定义UI组件状态的抽象类,如ComponentState,并为其定义更新、渲染等方法。
  • 具体状态类:创建具体的状态类,如HoverState(悬停状态)、ActiveState(激活状态)、DisabledState(禁用状态),在这些类中实现具体的UI逻辑。
  • 组件类:在组件类中,维护一个当前状态的引用,并根据状态的变化调用相应的方法来处理UI逻辑。

前端路由状态管理

在单页面应用(SPA)中,前端路由的状态管理是一个重要的问题。使用状态模式,可以清晰地管理路由的状态变化。

  • 状态定义:定义路由状态的抽象类,如RouteState,并为其定义导航、回退等方法。
  • 具体状态类:创建具体的状态类,如HomeState(首页状态)、DetailState(详情页状态)等,在这些类中实现具体的导航逻辑。
  • 路由管理类:在路由管理类中,维护一个当前路由状态的引用,并根据状态的变化调用相应的方法来处理导航逻辑。

综上所述,状态模式在前端框架中的应用十分广泛,可以用于管理复杂的用户交互逻辑、页面状态、游戏状态以及UI组件状态等。通过状态模式,可以使代码更加清晰、可维护和可扩展。

2、 Android 中的 View 状态

  • 在Android开发中,View(如Button)有多种状态,比如“正常状态”、“按下状态”、“不可用状态”等。这些状态的行为和外观是不同的。
// 定义抽象状态接口(简化版)
interface ViewState {void onDraw(Canvas canvas);boolean onTouchEvent(MotionEvent event);
}
// 正常状态类
class NormalState implements ViewState {@Overridepublic void onDraw(Canvas canvas) {// 绘制正常状态下的视图外观}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {// 切换到按下状态view.setState(view.getPressedState());return true;}return false;}
}
// 按下状态类
class PressedState implements ViewState {@Overridepublic void onDraw(Canvas canvas) {// 绘制按下状态下的视图外观}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_UP) {// 切换到正常状态或者执行点击操作等view.setState(view.getNormalState());return true;}return false;}
}
// 自定义View(环境类)
class CustomView extends View {private ViewState state;private ViewState normalState;private ViewState pressedState;public CustomView(Context context) {super(context);normalState = new NormalState();pressedState = new PressedState();state = normalState;}@Overrideprotected void onDraw(Canvas canvas) {state.onDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return state.onTouchEvent(event);}public void setState(ViewState state) {this.state = state;invalidate();}public ViewState getState() {return state;}public ViewState getNormalState() {return normalState;}public ViewState getPressedState() {return pressedState;}
}

六、应用场景

状态模式适用于以下场景:

  1. 必须在对象运行时改变对象的行为。
  2. 传统编程需要考虑所有可能发生的情况,使用条件选择语句if-else判断并选择执行。当新增状态时,需要新增if-else语句,程序扩展繁琐。针对条件表达式过于复杂,可以采用状态模式,分离判断逻辑变为一系列的状态类,使判断逻辑变得更加简单。

七、优缺点

优点

  1. 封装性强:每个状态都被封装成一个类,使得状态逻辑更加清晰,便于维护和扩展。
  2. 避免条件语句:通过状态模式可以避免使用大量的条件语句来控制对象的行为,使代码更加简洁和可读。
  3. 增强可扩展性:可以轻松地添加新的状态类,而不需要修改已有的代码,从而增强了系统的可扩展性。

缺点

  1. 状态类过多可能导致复杂性增加:如果系统中存在大量的状态类,可能会导致状态类之间的关系变得复杂,增加系统的理解和维护成本。
  2. 状态切换可能不够灵活:在某些情况下,状态切换可能受到限制,无法满足特定的业务需求。

综上所述,状态模式是一种非常有用的设计模式,可以有效地管理对象的状态和行为,并实现状态之间的转换逻辑。在实际应用中,应根据具体业务需求来设计状态类和上下文类,以确保模式的正确应用和系统的稳定性。

在这里插入图片描述

相关文章:

设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,使得对象看起来好像修改了它的类。这种设计模式的核心思想是将对象的状态和行为封装成不同的状态类,通过状态对象的行为改变来避免…...

计算机网络 (38)TCP的拥塞控制

前言 TCP拥塞控制是传输控制协议(Transmission Control Protocol,TCP)避免网络拥塞的算法,是互联网上主要的一个拥塞控制措施。 一、目的 TCP拥塞控制的主要目的是防止过多的数据注入到网络中,使网络能够承受现有的网络…...

鸿蒙面试 2025-01-09

鸿蒙分布式理念?(个人认为理解就好) 鸿蒙操作系统的分布式理念主要体现在其独特的“流转”能力和相关的分布式操作上。在鸿蒙系统中,“流转”是指涉多端的分布式操作,它打破了设备之间的界限,实现了多设备…...

【关于for循环的几种写法】

关于for循环的几种写法 在 C 中&#xff0c;for(int i 0; i < n; i) 是一种常见的循环写法&#xff0c;用于遍历从 0 到 n-1 的索引。如果你希望简化这种写法&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用范围 for 循环 如果你需要遍历一个容器&#xff08;如数…...

Apache和PHP:构建动态网站的黄金组合

在当今的互联网世界&#xff0c;网站已经成为了企业、个人和机构展示自己、与用户互动的重要平台。而在这些动态网站的背后&#xff0c;Apache和PHP无疑是最受开发者青睐的技术组合之一。这一组合提供了高效、灵活且可扩展的解决方案&#xff0c;帮助您快速搭建出强大的网站&am…...

免费开源的下载工具Xdown

软件介绍 Xdown是一款功能强大的开源免费下载工具&#xff0c;专为PC端用户设计&#xff0c;支持多种协议和下载方式。 1、多线程下载 Xdown支持最高128线程的并发下载&#xff0c;能够将文件分割成多个部分同时下载&#xff0c;从而显著提升下载速度。 2、多种协议支持 该…...

Three.js 数学工具:构建精确3D世界的基石

文章目录 前言一、向量&#xff08;Vectors&#xff09;二、矩阵&#xff08;Matrices&#xff09;三、四元数&#xff08;Quaternions&#xff09;四、欧拉角&#xff08;Euler Angles&#xff09;五、颜色&#xff08;Colors&#xff09;六、几何体生成器&#xff08;Geometr…...

如何明智地提问

如何明智地提问的重要总结&#xff0c;让我为主要观点添加一些具体的实践建议&#xff1a; 提问前的准备工作 尝试在 Google、Stack Overflow 等平台搜索相似问题阅读相关文档和错误日志尝试自己调试和排查问题记录下已尝试过的解决方案 选择合适的提问平台 Stack Overflow…...

Microsoft Sql Server 2019 函数理解

说到函数&#xff0c;首先和存储过程作个比较吧&#xff0c;两者有一个共同点都是预编译优化后存储在磁盘中&#xff0c;所以效率 要比T-SQL高一点点。值得注意的是&#xff0c;存储过程可以创建或访问临时表&#xff0c;而函数不可以&#xff1b; 同时函数不可 以修改表中的数…...

自定义日期转换配置

文章目录 1.日期问题出现原因以及解决方案概述1.图示2.三种解决方案概述1.对于表单数据 application/x-www-form-urlencoded2.对于JSON数据1.使用JsonFormat注解2.自定义Jackson日期转换配置 2.解决方案common-web-starter1.目录2.BaseController.java 使用InitBinder解决表单数…...

“AI智能服务平台系统,让生活更便捷、更智能

大家好&#xff0c;我是资深产品经理老王&#xff0c;今天咱们来聊聊一个让生活变得越来越方便的高科技产品——AI智能服务平台系统。这个系统可是现代服务业的一颗璀璨明珠&#xff0c;它究竟有哪些魅力呢&#xff1f;下面我就跟大家伙儿闲聊一下。 一、什么是AI智能服务平台系…...

SQL美化器优化

文章目录 1.目录2.代码 1.目录 2.代码 package com.sunxiansheng.mybatis.plus.inteceptor;import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.*…...

我的128天创作之路:回顾与展望

大家好呀&#xff01;今天来和你们分享一下我的创作历程&#x1f601;。 一、机缘 最开始创作呢&#xff0c;是因为在学习 C 的 STL 时&#xff0c;像 string、list、vector 这些模板可把我折腾得够呛&#xff0c;但也让我学到了超多东西&#xff01;我就想&#xff0c;要是把我…...

内核配置参数整理

#参考网页 linux5.2 &#xff1c;.config&#xff1e;文件注释 详细解释 CONFIG_ARMy&#xff1a;启用ARM架构支持&#xff0c;这是ARM处理器专用的内核配置选项。 CONFIG_ARM_HAS_SG_CHAINy&#xff1a;启用对散列表&#xff08;scatter-gather&#xff09;链的支持&#xf…...

SpringBoot整合Easy-es

一.什么是Easy-Es Easy-Es&#xff08;简称EE&#xff09;是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架&#xff0c;在 RestHighLevelClient 的基础上,只做增强不做改变&#xff0c;为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称…...

于交错的路径间:分支结构与逻辑判断的思维协奏

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一节内容很多&#xff0c;文章字数达到了史无前例的一万一&#xff0c;我们要来学习分支与循环结构中…...

Linux之读者写者模型与特殊锁的学习

目录 读者写者模型 特殊锁 悲观锁 自旋锁 在前几期&#xff0c;我们学习了多线程的生产者和消费者模型&#xff0c;生产者和消费者模型中&#xff0c;有三种关系&#xff0c;两个角色&#xff0c;一个场所&#xff0c;那么读者写者模型和生产者消费者模型有什么关联吗&…...

回溯专题 记录

回溯的题目按照这套模板进行&#xff1b; 我感觉整体逻辑还是递归&#xff0c;只不过有了pop_back才是回溯概念&#xff1b; class Solution {public:vector<int> path;vector<vector<int>> ans;void backtracking(int n,int k,int startindex){if(path.…...

使用 Python 实现自动化办公(邮件、Excel)

目录 一、Python 自动化办公的准备工作 1.1 安装必要的库 1.2 设置邮件服务 二、邮件自动化处理 2.1 发送邮件 示例代码 注意事项 2.2 接收和读取邮件 示例代码 三、Excel 自动化处理 3.1 读取和写入 Excel 文件 示例代码 3.2 数据处理和分析 示例代码 四、综合…...

贪心算法笔记

贪心算法笔记 大概内容 贪心就是对于一个问题有很多个步骤,我们在每一个步骤中都选取最优的那一个,最后得出答案。就是在一些函数中可行,但是有些比如二次函数,因为它的转折点不一定最优,就是不可行的。那么如何判断贪心呢?有这么几种 看时间复杂度,一般的就是 O ( n…...

Formality:两种等价状态consistency和equality

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 背景 逻辑锥的等价性检查时&#xff0c;存在两种验证模式&#xff1a;一致(consistency)和等同(equality)&#xff0c;要理解这两点&#xff0c;首先得明白综合工具…...

Java Web开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…...

第30章 汇编语言--- 性能优化技巧

汇编语言是用于直接编程计算机硬件的低级语言&#xff0c;它几乎是一对一地映射到机器指令。因为汇编代码与特定处理器架构紧密相关&#xff0c;所以在讨论性能优化技巧时&#xff0c;通常需要考虑具体的CPU架构和指令集。 以下是一些通用的汇编语言性能优化技巧&#xff0c;并…...

HTB:Paper[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 对靶机进行子域…...

数据库中的 DDL、DML 和 DCL

数据库中的 DDL、DML 和 DCL 在数据库的定义与操作中&#xff0c;DDL、DML 和 DCL 是三个核心概念&#xff0c;分别用于不同层面的数据库管理与操作。 1. DDL&#xff08;Data Definition Language&#xff09; - 数据定义语言 定义 DDL 用于定义和管理数据库的结构或模式。…...

OKR 极简史及理解

大家读完觉得有帮助记得点赞和关注&#xff01;&#xff01;&#xff01; 目录 MBO SMART 和 KPI OKR 1. 什么是 OKR&#xff1f; 1.1 Objectives&#xff08;目标&#xff09; 1.2 Key Results&#xff08;关键成果&#xff09; KR 应当是困难的&#xff0c;但并非不可…...

电商项目-基于ElasticSearch实现商品搜索功能(四)

一、 高亮显示 1.1 高亮分析 高亮显示是指根据商品关键字搜索商品的时候&#xff0c;显示的页面对关键字给定了特殊样式&#xff0c;让它显示更加突出&#xff0c;如商品搜索中&#xff0c;关键字变成了红色&#xff0c;其实就是给定了红色样式。 1.2 高亮搜索实现步骤解析 …...

TCP封装数据帧

void *send_data(void *arg) //这是一个发送数据的线程 {int sockfd init_tcp_cli("192.168.0.148",50000) //传ip和port&#xff0c;port 50000是因为大概前五万都被其它服务所占用&#xff0c;50000后是私人ipif(sockfd < 0){return NULL;}unsigned char …...

数据结构与算法之二叉树: LeetCode 515. 在每个树行中找最大值 (Ts版)

在每个树行中找最大值 https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/ 描述 给定一棵二叉树的根节点 root &#xff0c;请找出该二叉树中每一层的最大值 示例1 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2 输入: root [1,2,3]…...

百度视频搜索架构演进

导读 随着信息技术的迅猛发展&#xff0c;搜索引擎作为人们获取信息的主要途径&#xff0c;其背后的技术架构也在不断演进。本文详细阐述了近年来视频搜索排序框架的重大变革&#xff0c;特别是在大模型技术需求驱动下&#xff0c;如何从传统的多阶段级联框架逐步演变为更加高…...

杭州网站提升排名/软文街官方网站

人们日常熟知的邮政业务包括邮务业务、快递业务、银行业务、保险业务、证券业务、网上商城等&#xff0c;除此之外&#xff0c;还有一项非常重要——电商业务。区别于人们熟知的电商网购&#xff0c;邮政公司电商业务主要是指人们日常生活中的代收费业务&#xff08;包括水、电…...

wordpress 每日替换/网站优化推广培训

关注、星标嵌入式客栈&#xff0c;精彩及时送达[导读] 你是否被要求写的代码需要0 erros, 0 warnings? 或者你的项目是否需要做静态代码检测&#xff1f;0 erros是一定要做到&#xff0c;而0 wanring有时候会让你抓狂。前面转了一篇数组内包含头文件的写法&#xff0c;看起来对…...

成都青羊建设厅官方网站/seo推广软件哪个好

双子序列和Description: 描述&#xff1a; This is a standard interview problem to print the longest Bitonic subsequence using Dynamic programming. 这是使用动态编程打印最长的Bitonic子序列的标准面试问题。 Problem statement: 问题陈述&#xff1a; Given an arr…...

设计人才网官网/无锡百度关键词优化

本文章仅代表个人观点&#xff0c;如有错误缺漏&#xff0c;欢迎指正。广义切比雪夫滤波器原型是现在广泛使用的滤波器函数&#xff0c;因其把有切比雪夫滤波器无限元处的传输零点移到有限远处(可以是近带外)&#xff0c;使近带外的抑制特性更好。1.广义切比雪夫滤波器原型由广…...

在家做兼职的网站/百度官方版

程序的速度应该每过一两年就会增加一倍&#xff0c;因为摩尔定律预言处理器性能会每隔18个月翻一番。但在多核时代&#xff0c;单核的性能趋于平稳&#xff0c;而计算机软件还无法充分利用多个核心的全部功能&#xff0c;原因与程序的多线程代码有关。现在&#xff0c;微软研究…...

做网站1g网页空间够吗/如何制作网页设计

2019独角兽企业重金招聘Python工程师标准>>> 在Centos7 系统中使用supermin制作CentOS6 的Docker镜像 jin771998569关注0人评论1499人阅读2018-01-19 17:08:40 使用supermin制作CentOS的Docker镜像 需求 supermin 在Centos7 里面安装默认只能够构建Centos7 版本的基…...