设计模式 行为型 状态模式(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. 状态切换可能不够灵活:在某些情况下,状态切换可能受到限制,无法满足特定的业务需求。

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

在这里插入图片描述

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

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

相关文章

某团 mtgsig1.2 | sdkVersion: 3.0.0 签名算法分析记录(2025/1/9)

【作者主页】:小鱼神1024 【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码&#…

(二)最长公共子序列、最长上升子序列、最大子段和、三角形最小路径和、矩阵连乘、0-1背包

最近刚考完算法设计分析课的考试,复习总结一下期末考试的几道算法题吧 目录 LCR 095. 最长公共子序列 300. 最长递增子序列 53. 最大子数组和 LCR 100. 三角形最小路径和 矩阵连乘问题 0-1背包 LCR 095. 最长公共子序列 给定两个字符串 text1 和 text2&#xff…

聚类系列 (二)——HDBSCAN算法详解

在进行组会汇报的时候,为了引出本研究动机(论文尚未发表,暂不介绍),需要对DBSCAN、OPTICS、和HDBSCAN算法等进行详细介绍。在查询相关资料的时候,发现网络上对于DBSCAN算法的介绍非常多与细致,但…

通义灵码在跨领域应用拓展之物联网篇

目录 一.引言 二.通义灵码简介 三.通义灵码在物联网领域的设备端应用 1.传感器数据采集 (1).不同类型传感器的数据读取 (2).数据转换与预处理 2.设备控制指令接收和执行 (1).指令解析与处理 (2).设备动作执行 四.通义灵码在物联网领域的云端平台应用 1.数据存储和管…

DolphinScheduler自身容错导致的服务器持续崩溃重大问题的排查与解决

01 问题复现 在DolphinScheduler中有如下一个Shell任务: current_timestamp() { date "%Y-%m-%d %H:%M:%S" }TIMESTAMP$(current_timestamp) echo $TIMESTAMP sleep 60 在DolphinScheduler将工作流执行策略设置为并行: 定时周期调度设置…

CISAW-ES应急服务方向信息安全事件分级

网络安全事件事件分级 网络安全事件分为四级:特别重大网络安全事件、重大网络安全事大网络安全事件、一般网络安全事件。 1.特别重大网络安全事件 符合下列情形之一的,为特别重大网络安全事件。 (1)重要网络和信息系…

油猴支持阿里云自动登陆插件

遇到的以下问题,都已在脚本中解决: 获取到的元素赋值在页面显示,但是底层的value并没有改写,导致请求就是获取不到数据元素的加载时机不定,尤其是弱网情况下,只靠延迟还是有可能获取不到,且登陆不丝滑,通过元素发现机制,解决此问题并做到丝滑登陆根据密钥计算校验码之…

B树与B+树:数据库索引的秘密武器

想象一下,你正在构建一个超级大的图书馆,里面摆满了各种各样的书籍。B树和B树就像是两种不同的图书分类和摆放方式,它们都能帮助你快速找到想要的书籍,但各有特点。 B树就像是一个传统的图书馆摆放方式: 1. 书籍摆放&…

城市生命线安全综合监管平台

【落地产品,有需要可留言联系,支持项目合作或源码合作】 一、建设背景 以关于城市安全的重要论述为建设纲要,聚焦城市安全重点领域,围绕燃气爆炸、城市内涝、地下管线交互风险、第三方施工破坏、供水爆管、桥梁坍塌、道路塌陷七…

成为LabVIEW自由开发者

成为LabVIEW自由开发者的体验可以非常丰富且具有挑战性,同时也充满了自我成长和多样化项目的机会。 ​ 1. 高度的灵活性与自由度 工作时间与地点:作为自由开发者,你可以自由选择工作时间和地点。你可以在家工作,也可以选择在咖啡…

用于与多个数据库聊天的智能 SQL 代理问答和 RAG 系统(3) —— 基于 LangChain 框架的文档检索与问答功能以及RAG Tool的使用

介绍基于 LangChain 框架的文档检索与问答功能,目标是通过查询存储的向量数据库(VectorDB),为用户的问题检索相关内容,并生成自然语言的答案。以下是代码逻辑的详细解析: 代码结构与功能 初始化环境与加载…

基于QT和C++的实时日期和时间显示

一、显示在右下角 1、timer.cpp #include "timer.h" #include "ui_timer.h" #include <QStatusBar> #include <QDateTime> #include <QMenuBar> Timer::Timer(QWidget *parent) :QMainWindow(parent),ui(new Ui::Timer) {ui->setup…

Elasticsearch学习(1) : 简介、索引库操作、文档操作、RestAPI、RestClient操作

目录 1.elasticsearch简介1.1.了解es1.2.倒排索引正向索引和倒排索引 1.3.es的一些概念:文档和字段&#xff1b;索引和映射&#xff1b;Mysql与ES1.4.安装es、kibana部署单点es部署kibanaIK分词器安装IK分词器与测试扩展与停用词词典总结 部署es集群 2.索引库操作2.1.mapping映…

【LeetCode Hot100 贪心算法】 买卖股票的最佳时机、跳跃游戏、划分字母区间

贪心算法 买卖股票的最佳时机买卖股票的最佳时机II跳跃游戏跳跃游戏II划分字母区间 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的…

如何在 Ubuntu 22.04 上使用 LEMP 安装 WordPress 教程

简介&#xff1a; 本教程旨在指导你如何在 Ubuntu 22.04 上使用 LEMP 栈安装 WordPress。 WordPress 是一个用 PHP 编写的开源内容管理系统。LEMP 栈是 Linux&#xff0c;NGINX&#xff0c;MySQL 和 PHP 的缩写。WordPress 非常用户友好&#xff0c;并提供了多种选项&#xff…

vue实现虚拟列表滚动

<template> <div class"cont"> //box 视图区域Y轴滚动 滚动的是box盒子 滚动条显示的也是因为box<div class"box">//itemBox。 一个空白的盒子 计算高度为所有数据的高度 固定每一条数据高度为50px<div class"itemBox" :st…

STM32小实验2

定时器实验 TIM介绍 TIM&#xff08;Timer&#xff09;定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断…

HTB:Timelapse[WriteUP]

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

【贵州省】乡镇界arcgis格式shp数据乡镇名称和编码内容下载测评

shp数据字段乡镇名称和编码&#xff0c;坐标是wgs84&#xff0c;数据为SHP矢量格式&#xff0c;下载下来直接加载进ArcMap即可使用 下载地址&#xff1a;https://download.csdn.net/download/zhongguonanren99/14928126

[免费]微信小程序(高校就业)招聘系统(Springboot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序(高校就业)招聘系统(Springboot后端Vue管理端)&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序(高校就业)招聘系统(Springboot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项目介绍…