前端开发设计模式——状态模式
目录
一、状态模式的定义和特点
二、状态模式的结构与原理
1.结构:
2.原理:
三、状态模式的实现方式
四、状态模式的使用场景
1.按钮的不同状态:
2.页面加载状态:
3.用户登录状态:
五、状态模式的优点
1.提高代码的可维护性:
2.增强代码的可读性:
3.更好的处理动态变化:
六、状态模式的缺点
1.增加了代码的复杂性:
2.可能会增加内存占用:
七、状态模式的注意事项
1.状态的划分要合理:
2.状态的转换要清晰:
3.注意性能问题:
一、状态模式的定义和特点
定义:状态模式允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
特点:
将状态的行为封装在独立的状态类中,使得状态的转换更加清晰、可维护。
减少了条件判断语句,使代码更加简洁、易于理解。
实现了状态与行为的解耦,使得状态的变化不会影响到对象的其他部分。
二、状态模式的结构与原理
1.结构:
1.1 状态接口:
定义了一组方法,这些方法代表了对象在不同状态下的行为。
1.2 具体状态类:
实现状态接口,每个具体状态类代表对象的一种特定状态,并实现与该状态相关的行为。
1.3 上下文对象:
拥有一个对当前状态的引用,并将与状态相关的操作委托给当前状态对象。当上下文对象的内部状态发生变化时,它会切换到不同的具体状态类,从而改变其行为。
2.原理:
通过将对象的行为与状态分离,使得对象可以在不同的状态下表现出不同的行为。当对象的状态发生变化时,它会自动切换到相应的状态类,执行该状态下的行为。
三、状态模式的实现方式
步骤:
1.定义状态接口,明确在不同状态下需要实现的方法。
示例:
class State {handleEvent() {throw new Error('This method must be overridden.');}
}
2.创建具体状态类,实现状态接口,并在每个类中实现特定状态下的行为。
示例:
class StateA extends State {handleEvent() {console.log('In State A.');// 执行状态 A 下的特定行为}
}class StateB extends State {handleEvent() {console.log('In State B.');// 执行状态 B 下的特定行为}
}
3.在上下文对象中,维护一个对当前状态的引用,并提供方法来设置和切换状态。上下文对象将与状态相关的操作委托给当前状态对象执行。
示例:
class Context {constructor() {this.state = new StateA();}setState(state) {this.state = state;}handleEvent() {this.state.handleEvent();}
}
四、状态模式的使用场景
1.按钮的不同状态:
例如按钮有正常状态、禁用状态、鼠标悬停状态等,每个状态下的行为不同,可以使用状态模式来管理这些状态和行为。
2.页面加载状态:
页面在加载数据时可能处于不同的状态,如正在加载、加载成功、加载失败等,可以使用状态模式来处理不同状态下的显示和交互。
示例:
假设我们正在开发一个新闻资讯类的网页应用。当用户打开页面时,页面需要从服务器获取新闻数据并展示给用户。在这个过程中,页面会经历不同的状态:
(1)正在加载状态:页面刚打开时,显示一个加载动画,告知用户数据正在加载中。此时可以创建一个 “加载中” 的状态类,比如:
class LoadingState {show() {document.getElementById('content').innerHTML = '<div class="loader">Loading...</div>';}
}
(2)加载成功状态:当数据成功从服务器返回并渲染到页面上时,显示新闻列表。创建一个 “加载成功” 的状态类
class SuccessState {show(data) {let html = '';data.forEach(item => {html += `<div>${item.title}</div>`;});document.getElementById('content').innerHTML = html;}
}
(3)加载失败状态:如果数据加载过程中出现错误,显示错误提示信息。对应的状态类如下:
class ErrorState {show() {document.getElementById('content').innerHTML = '<div class="error">Failed to load data.</div>';}
}
然后创建一个上下文对象来管理这些状态:
class PageStateContext {constructor() {this.state = new LoadingState();}setState(state) {this.state = state;}show() {this.state.show();}
}
在实际使用中,可以根据不同的情况切换状态:
const context = new PageStateContext();
// 模拟数据加载
setTimeout(() => {const isSuccess = Math.random() > 0.5;if (isSuccess) {const data = [{ title: 'News 1' },{ title: 'News 2' }];context.setState(new SuccessState());context.show(data);} else {context.setState(new ErrorState());context.show();}
}, 2000);
3.用户登录状态:
用户在未登录、登录中、已登录等状态下,页面的显示和功能会有所不同,可以使用状态模式来管理这些状态。
示例:
在一个社交类的前端应用中,用户的登录状态会影响页面的显示和功能。可以使用状态模式来管理用户的登录状态:
(1)未登录状态:显示登录按钮和注册链接。状态类如下:
class NotLoggedInState {show() {document.getElementById('userArea').innerHTML = '<button>Login</button><a href="#">Register</a>';}
}
(2) 登录中状态:显示加载动画,提示用户正在登录。状态类为:
class LoggingInState {show() {document.getElementById('userArea').innerHTML = '<div class="loader">Logging in...</div>';}
}
(3) 已登录状态:显示用户头像和用户名,以及退出登录按钮。状态类如下:
class LoggedInState {show(user) {document.getElementById('userArea').innerHTML = `<img src="${user.avatar}" alt="Avatar"><span>${user.username}</span><button>Logout</button>`;}
}
创建上下文对象来管理这些状态:
class UserStateContext {constructor() {this.state = new NotLoggedInState();}setState(state) {this.state = state;}show() {this.state.show();}
}
在实际应用中,可以根据用户的操作切换状态:
const context = new UserStateContext();
// 模拟用户点击登录按钮
document.getElementById('loginButton').addEventListener('click', () => {context.setState(new LoggingInState());context.show();// 模拟登录成功setTimeout(() => {const user = { username: 'John', avatar: 'avatar.jpg' };context.setState(new LoggedInState());context.show(user);}, 2000);
});
// 模拟用户点击退出登录按钮
document.getElementById('logoutButton').addEventListener('click', () => {context.setState(new NotLoggedInState());context.show();
});
五、状态模式的优点
1.提高代码的可维护性:
状态和行为的分离使得代码更加清晰,易于修改和扩展。
2.增强代码的可读性:
通过将状态的行为封装在独立的类中,使得代码的逻辑更加清晰,易于理解。
3.更好的处理动态变化:
可以轻松地添加新的状态和行为,适应不断变化的需求。
六、状态模式的缺点
1.增加了代码的复杂性:
引入了更多的类和对象,可能会使代码结构变得更加复杂。
2.可能会增加内存占用:
每个状态都需要一个具体的状态类实例,可能会占用更多的内存。
七、状态模式的注意事项
1.状态的划分要合理:
根据实际需求合理划分状态,避免状态过多或过少。
2.状态的转换要清晰:
确保状态之间的转换逻辑清晰,避免出现混乱的状态转换。
3.注意性能问题:
如果状态的切换非常频繁,可能会影响性能,可以考虑优化状态的管理方式。
关于状态模式的介绍就到此结束,如果对于其他设计模式感兴趣的话,可以看看下方的专栏目录,里面有其他设计模式的文章。码字不易,点个赞再走吧

相关文章:
前端开发设计模式——状态模式
目录 一、状态模式的定义和特点 二、状态模式的结构与原理 1.结构: 2.原理: 三、状态模式的实现方式 四、状态模式的使用场景 1.按钮的不同状态: 2.页面加载状态: 3.用户登录状态: 五、状态模式的优点 1.提…...
特种作业操作烟花爆竹试题分享
1.(单选题)职业卫生研究的是人类从事各种职业劳动过程中的( )。 A.健康问题 B.环境问题 C.卫生问题 答案:C 2.(单选题)安全生产事关人民群众的( )安全,事关改革发展和…...
实现prometheus+grafana的监控部署
直接贴部署用的文件信息了 kubectl label node xxx monitoringtrue 创建命名空间 kubectl create ns monitoring 部署operator kubectl apply -f operator-rbac.yml kubectl apply -f operator-dp.yml kubectl apply -f operator-crd.yml # 定义node-export kubectl app…...
确保Spring Boot定时任务只执行一次方案
在Spring Boot项目中,确保定时任务只执行一次是一个常见的需求。这种需求可以通过多种方式来实现,以下是一些常见的方法,它们各具特点,可以根据项目的实际需求来选择最合适的方法。 1. 使用Scheduled注解并设置极大延迟 一种简单…...
【Python数据可视化】利用Matplotlib绘制美丽图表!
【Python数据可视化】利用Matplotlib绘制美丽图表! 数据可视化是数据分析过程中的重要步骤,它能直观地展示数据的趋势、分布和相关性,帮助我们做出明智的决策。在 Python 中,Matplotlib 是最常用的可视化库之一,它功能…...
【最新通知】2024年Cisco思科认证CCNA详解
CCNA现在涵盖安全性、自动化和可编程性。该计划拥有一项涵盖IT职业基础知识的认证,包括一门考试和一门培训课程,助您做好准备。 CCNA培训课程和考试最近面向最新技术和工作岗位进行了重新调整,为您提供了向任何方向发展事业所需的基础。CCNA认…...
监控内容、监控指标、监控工具大科普
在现代信息技术领域,监控技术扮演着至关重要的角色。它帮助我们实时了解系统、网络、应用以及环境的状态,确保它们的安全、稳定和高效运行。以下是对监控内容、监控指标和监控工具的详细科普。 一、监控内容 监控内容是指监控系统所关注和记录的具体信…...
生成文件夹 - python 实现
生成文件夹保存图片和文本等信息。 代码具体实现如下: #-*-coding:utf-8-*- # date:2021-04-13 # Author: DataBall - XIAN # Function: 生成文件夹import os if __name__ "__main__":path "./dataset"if not os.path.exists(path): # 如果…...
快速了解学会python基础语言及IDLE 提供的常用快捷键
😀前言 本篇博文是关于python的基础语言介绍及IDLE 提供的常用快捷键,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的…...
【python】OpenCV—Sort the Point Set from Top Left to Bottom Right
文章目录 1、功能描述2、代码实现3、效果展示4、更多例子5、参考 1、功能描述 给出一张图片,里面含有各种图形,取各种图形的中心点,从左到右从上到下排序 例如 2、代码实现 import cv2 import numpy as npdef process_img(img):img_gray c…...
LeetCode 1493.删掉一个元素以后全为1的最长子数组
题目: 给你一个二进制数组 nums ,你需要从中删掉一个元素。 请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。 如果不存在这样的子数组,请返回 0 。 思路:不定长滑动窗口,将问题…...
php常用设计模式之工厂模式
引言 在日常开发中,我们一些业务场景需要用到发送短信通知。然而实际情况考虑到不同厂商之间的价格、实效性、可能会出现的情况等 我们的业务场景往往会接入多个短信厂商来保证我们业务的正常运行,而不同的短信厂商(如阿里云短信、腾讯云短信…...
通用软件版本标识
软件版本标识:了解不同的版本类型 在软件开发和发布过程中,版本号和标识扮演着重要的角色。它们不仅帮助开发者追踪软件的演变,还让用户了解软件的稳定性和功能。以下是一些常见的软件版本标识,以及它们的含义和用途。 Alpha&am…...
(计算机毕设)基于SpringBoot的就业平台开题报告
一、立题依据(国内外研究进展或选题背景、研究意义等) 国内外研究进展或选题背景 在全球化的大背景下,就业问题一直是各国政府和社会各界关注的焦点。随着互联网技术的普及和发展,网络招聘已成为求职者和企业招聘的主要渠道。据相关数据显示࿰…...
STM32G4系列MCU的ADC模块标定方法和采样时间
目录 概述 1 ADC模块标定 1.1 功能介绍 1.2 软件程序校准ADC 1.2.1 标定步骤 1.2.2 标定时序框图 1.3 软件程序重新注入校准因子到ADC 1.3.1 标定步骤 1.3.2 更新ADC校准因子 1.4 用单个ADC转换单端和差分模拟输入 1.4.1 标定流程 1.4.2 混合单端和差分通道 2 通道…...
NVIDIA Jetson支持的神经网络加速的量化平台
NVIDIA Jetson支持的神经网络加速的量化工具、技术 NVIDIA Jetson 是专为边缘计算和嵌入式系统设计的高性能计算平台,它支持多种深度学习模型的部署和推理。对于神经网络加速的量化平台,Jetson 支持以下技术和工具: TensorRT:Ten…...
MySQL 免密登录的几种配置方式
文章目录 MySQL 免密登录的几种配置方式使用操作系统用户实现免密登录具体步骤:Step 1: 修改 MySQL 配置文件Step 2: 重启 MySQL 服务Step 3: 使用系统用户登录 MySQL优点:缺点: 使用 mysql_config_editor 配置免密文件具体步骤:S…...
html全局属性、框架标签
常用的全局属性: 属性名含义id 给标签指定唯一标识,注意:id是不能重复的。 作用:可以让label标签与表单控件相关联;也可以与css、JavaScript配合使用。 注意:不能再以下HTML元素中使用:<hea…...
ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)
关注这个工具的其它相关内容:自动化信息收集工具 —— ARL 灯塔使用手册 - CSDN 博客 灯塔,全称:ARL 资产侦察灯塔系统,有着域名资产发现和整理、IP/IP 段资产整理、端口扫描和服务识别、WEB 站点指纹识别、资产分组管理和搜索等等…...
抖音列表页采集-前言
准备工作: 1.关于selenium介绍: python自动化入门的话,selenium绝对是最方便的选择,基本逻辑即为:程序模拟人的行为操作浏览器,这样的操作需要借用浏览器驱动,我选用的是chrome浏览器ÿ…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
