设计模式-状态模式
介绍
- 一个对象有状态变化
- 每次状态变化都会触发一个逻辑
- 不能总是用
if else来控制
示例
- 交通信号灯不同颜色的变化
UML类图
-
传统UML类图

-
简化后的UML类图

代码演示
// 状态(红灯、绿灯、黄灯)
class State {constructor(color) {this.color = color;}// 设置状态handle(context) {console.log(`turn to ${this.color} light`)context.setState(this)}
}// 主体
class Context {consructor() {this.state = null}// 获取状态getState() {return this.state}setState(state) {this.state = state}
}// test
let context = new Context()let green = new State('green')
let yellow = new State('yellow')
let red = new State('red')// 绿灯亮了
green.handle(context)
console.log(context.getState())
场景
有限状态机
- 有限个状态、以及在这些状态之间的变化
- 如交通信号灯
- 使用开源lib:javascript-state-machine
- github.com/jakesgordon/javascript-state-machine
有限状态机- “收藏”和“取消”
// 状态机模型
var fsm = new StateMachine({init: '收藏', // 初始状态,待收藏transitions: [{name: 'doStore',from: '收藏',to: '取消收藏'},{name: 'deleteStore',from: '取消收藏',to: '收藏'}],methods: {// 执行收藏onDoStore: function () {alert('收藏成功')updateText()},// 取消收藏onDeleteStore: function () {alert('已取消收藏')updateText()}}
})var $btn = $('#btn')// 点击事件
$btn.click(function() {if (fsm.is('收藏')) {fsm.doStore()} else {fsm.deleteStore()}
})// 更新文案
function updateText() {$btn.text(fsm.state)
}// 初始化文案
updateText()
写一个简单的Promise
- 回顾Promise的语法
function loadImg(src) {const promise = new Promise(function (resolve, reject) {var img = document.createElement('img');img.onload = function() {resolve(img)}img.onerror = function() {reject()}img.src = src})return promise
}var src = '';
var result = loadImg(src)result.then(function(img){console.log('success 1')
}, function() {console.log('failed 1')
})
result.then(function(img) {console.log('success 2')
}, function() {console.log('failed 2')
})
-
分析:Promise就是一个有限状态机
- Promise三种状态:pending fullfilled rejected
- pending -> fullfilled或者 pending -> rejected
- 不能逆向变化
-
写代码
// 模型
var fsm = new StateMachine({init: 'pending',transitions: [{name: 'resolve',from: 'pending',to: 'fullfilled'},{name: 'reject',from: 'pending',to: 'rejected'}],methods: {// 成功onResolve: function (state, data) {// 参数:state - 当前状态实例;data - fsm.resolve(xxx) 执行时传递过来的参数data.successList.forEach(fn => fn())},// 失败onReject: function (state, data) {// 参数: state - 当前状态实例;data - fsm.reject(xxx) 执行时传递过来的参数data.failList.forEach(fn => fn())}}
})// 定义Promise
class MyPromise {// fn 回调函数constructor(fn) {this.successList = []this.failList = []// 接收两个函数参数,第一个为resolve回调,第二个为reject回调fn(() => {// resolve 函数 fsm.resolve(this) // fsm触发onResolve函数}, () => {// reject 函数fsm.reject(this) // fsm触发onResolve函数})}// then函数,successFn failFn 不会立即执行,放进数组里then(successFn, failFn) {this.successList.push(successFn)this.failList.push(failFn)}
}// 测试代码
function loadImg(src) {const promise = new MyPromise(function (resolve, reject) {let img = document.createElement('img')img.onload = function() {resolve(img)}img.onerror = function() {reject()}img.src = src})return promise
}let src = 'https://imgxxx';
let result = loadImg(src)result.then(function() {console.log('ok1')
}, function() {console.log('fail1')
})result.then(function() {console.log('ok2')
}, function() {console.log('fail2')
})
设计原则验证
- 将状态对象和主题对象分离,状态的变化逻辑单独处理
- 符合开放封闭原则
相关文章:
设计模式-状态模式
介绍 一个对象有状态变化每次状态变化都会触发一个逻辑不能总是用if else来控制 示例 交通信号灯不同颜色的变化 UML类图 传统UML类图 简化后的UML类图 代码演示 // 状态(红灯、绿灯、黄灯) class State {constructor(color) {this.color col…...
支持多种格式照片处理软件Lightroom Classic 2022 mac中文功能特点
Lightroom Classic 2022 mac是一款专业级数字图像处理软件,主要用于数字照片的后期处理和管理。它提供了丰富的工具和功能,可以帮助用户对照片进行调整、修饰、管理和分享。 Lightroom Classic 2022 mac软件功能和特点 RAW格式支持:Lightroo…...
UML简介
UML,全称为Unified Modeling Language(统一建模语言),是一种用于软件工程和系统设计的标准化建模语言。它提供了一套图形化的符号和标记,用于描述和表示软件系统、系统架构、流程、数据结构、行为和交互。UML的设计旨在…...
【PostgreSQL内核学习(十七)—— (AutoAnalyze)】
AutoAnalyze 概述AutoAnaProcess 类AutoAnaProcess 函数AutoAnaProcess::executeSQLCommand 函数AutoAnaProcess::runAutoAnalyze 函数AutoAnaProcess::run 函数AutoAnaProcess::check_conditions 函数AutoAnaProcess::cancelAutoAnalyze 函数AutoAnaProcess::~AutoAnaProcess …...
C++中指向成员的指针运算符(.* 和 ->*)用法说明
目录 一 MSDN中使用说明1.1 语法1.2 备注 二 一个使用案例 一 MSDN中使用说明 1.1 语法 expression .* expression //直接成员解除引用运算符 expression –>* expression //间接成员解除引用运算符 1.2 备注 C中指向成员的指针运算符(.* 和 ->*)…...
ASUS华硕ZenBook灵耀X逍遥UXF3000E_UX363EA原装出厂预装Win11系统工厂模式安装包
下载链接:https://pan.baidu.com/s/1WLPp0e5AZErtX3bJIhTZMg?pwd2j7i 带有ASUS Recovery恢复功能、自带所有驱动、出厂主题壁纸、Office办公软件、MyASUS华硕电脑管家等预装程序 所需要工具:16G或以上的U盘(非必需) 文件格式:HDI,SWP,OFS,E…...
【数据结构】栈和队列-- OJ
目录 一 用队列实现栈 二 用栈实现队列 三 设计循环队列 四 有效的括号 一 用队列实现栈 225. 用队列实现栈 - 力扣(LeetCode) typedef int QDataType; typedef struct QueueNode {struct QueueNode* next;QDataType data; }QNode;typedef struct …...
访问Apache Tomcat的管理页面
配置访问Tomcat管理页面的用户名、密码、角色 Tomcat安装完成后,包含了一个管理应用,默认安装在 <Tomcat安装目录>/webapps/manager 例如: 要使用管理页面的功能,需要在conf/tomcat-users.xml文件中配置用户、密码及角色…...
企业组织内如何避免山头文化?
1,什么是山头文化 2,山头文化的危害 3,如何避免山头文化 01什么是山头文化 山头文化就是指某一组织中的一部分人员组成一个以共同利益为基础的集体,就如同古代占山头一样,在组织中形成一股无形的力量,其…...
【c#】线程Monitor.Wait和Monitor.Pulse使用
介绍 以一个简易版的数据库连接池的实现来说明一下 连接池的connection以队列来管理 getConnection的时候,如果队列中connection个数小于50,且暂时无可用的connection(个数为0或者peek看下头部需要先出那个元素还处于不可用状态)…...
GitLab平台安装中经典安装语句含义解析
yum -y install policycoreutils openssh-server openssh-clients postfix 这是一个Linux命令,用于使用YUM包管理器安装指定的软件包。下面是对这个命令各部分的解释: yum:这是一个Linux命令行工具,用于管理RPM(Red …...
湘潭大学 2023年下学期《C语言》作业0x03-循环1 XTU OJ 1094,1095,1096,1112,1113
第一题 #include<stdio.h>int main() {int t;int count1;scanf("%d",&t);while(t--){int a,b,c;scanf("%d%d",&a,&b);cab;printf("Case %d: %d\n",count,c);count;}return 0; } 记住多样例输入的模板,熟悉计数器…...
【Linux系统满足产品实时性需求】
一、背景: 应用实时性:应用程序1以固定周期执行实时算法; 应用程序2以固定周期,执行串口收发; 驱动实时性:驱动sdio接口,实现与FPGA数据交互,实现串口数据收发。 二、实时性保证&…...
不用休眠的 Kotlin 并发:深入对比 delay() 和 sleep()
本文翻译自: https://blog.shreyaspatil.dev/sleepless-concurrency-delay-vs-threadsleep 毫无疑问,Kotlin 语言中的协程 Coroutine 极大地帮助了开发者更加容易地处理异步编程。该特性中封装的诸多高效 API,可以确保开发者花费更小的精力去…...
在Ubuntu中批量创建用户
一、背景知识 在Linux操作系统中创建新用户可以使用useradd或adduser命令。 使用useradd命令创建用户时,不会在/home目录下创建用户文件夹,需要用户自己指定主目录和bash目录的位置。同时,创建的用户没有设置密码,无法进行登录&a…...
汽车冲压车间的RFID技术设计解决方案
一、RFID技术的基本原理 RFID技术是一种利用非接触式自动识别的技术,通过将RFID标签放置在被识别物品上,并使用RFID读写器对标签进行扫描和识别,实现对物品的自动识别和追踪。RFID标签分为被动式和主动式两种。被动式标签无内置电源…...
TCP 和UDP通信流程
TCP 通信流程 根据上图可以看到,TCP 服务器和客户端通信分为 TCP 服务端和客户端,需要先建立服务 端然后再建立客户端与之连接进行数据交互。 服务端编程步骤: 1.使用 socket 创建流式套接字 2.使用 bind 绑定将服务器绑定到 IP 3.listen…...
Swift SwiftUI CoreData 过滤数据 1
Xcode: Version 14.3.1 (14E300c) iOS: 16 预览: Code: import SwiftUI import CoreDatastruct TodosSearch: View {State private var search_title "测试"FetchRequest var todos_search: FetchedResults<Todo>init() {let request: NSFetchReq…...
【uniapp】subnvue组件数据更新视图未更新问题
背景 : 页面中的弹窗使用了subnvue来写, 根据数据依次展示一个一个的弹窗, 点击"关闭"按钮关闭当前弹窗, 显示下一个弹窗 问题 : 当点击关闭时( 使用的splice() ), 数据更新了 , 而视图没有更新, 实际上splice() 是不仅更新数据, 也可以更新视图的 解决 : this.$fo…...
Unity编辑器拓展-Odin
1.相比于原生Unity的优势 Unity不支持泛型类型序列化,例如字典原生Unity不支持序列化,而Odin可以继承序列化的Mono实现功能强大且使用简单,原生Unity想实现一些常见的功能需要额外自己编写Unity扩展的编码,实现功能只需要加一个特…...
MoveIt Config 配置文件完整一致性检查
检查范围(全部核对完毕)ros2_control xacro(硬件接口 / 关节)initial_positions.yaml(初始位置)srdf(运动组 / 关节)joint_limits.yaml(关节限制)kinematics.…...
从拼图游戏到自动驾驶:点云配准技术的跨领域进化史
从拼图游戏到自动驾驶:点云配准技术的跨领域进化史 1. 三维世界的数字拼图师 1987年,当Paul Besl和Neil McKay在实验室里尝试将两组扫描数据对齐时,他们可能不会想到,这项被称为迭代最近点(ICP)的技术会成为…...
告别传统架构!源网荷储四侧时序数据库选型与落地全解析
新型电力系统应该用什么数据库?源网荷储四侧的时序数据库选型与落地实战 “双碳” 目标的推进正在深刻重构电力系统的运行逻辑。新能源装机占比持续攀升,储能、虚拟电厂、需求响应等新业态快速涌现,源、网、荷、储各侧的角色与互动方式正在被…...
MX28智能舵机RS485底层驱动开发实战
1. MX28智能舵机底层驱动技术解析:基于RS485总线的嵌入式控制实现1.1 技术定位与工程价值MX28是Robotis公司推出的第二代高精度智能舵机(Smart Actuator),采用RS485半双工差分总线通信,支持位置、速度、扭矩闭环控制及…...
【收藏干货】IndexRAG:离线生成桥接事实,实现单次检索的多跳推理
plaintext IndexRAG: Bridging Facts for Cross-Document Reasoning at Index Timehttps://arxiv.org/pdf/2603.16415 ### 一、多跳QA的困境多跳问答(Multi-hop QA)要求模型跨越多篇文档进行推理,比如回答"电影Aylwin的导演出生在哪里&q…...
Go 协程池设计与调度实现
Go 协程池设计与调度实现 在并发编程中,Go 语言的协程(goroutine)以其轻量级和高性能著称。无限制地创建协程可能导致资源耗尽,影响系统稳定性。为此,协程池的设计与调度成为优化高并发场景的重要手段。本文将深入探讨…...
SparkFun ICM-20948 Arduino库:DMP硬件协处理器深度实践指南
1. 项目概述SparkFun ICM-20948 Arduino Library 是面向 TDK InvenSense ICM-20948 九轴惯性测量单元(9DoF IMU)的官方 Arduino 封装库,专为 SparkFun 9DoF IMU Breakout - ICM-20948(Qwiic 接口版本,型号 SEN-15335&a…...
Simulink三相变压器模块深度解析:从参数配置到电力系统仿真实战
1. 三相变压器模块的核心功能解析 Simulink中的Three-Phase Transformer模块就像电力系统的"翻译官",专门负责处理三相交流电的电压转换和相位调整。我在电力电子项目中最常使用的就是这个模块,因为它能完美还原真实变压器的各种"脾气秉…...
Debugging torch.distributed.DistBackendError: NCCL Communicator Setup and ncclUniqueId Retrieval Iss
1. 理解NCCL通信错误的核心问题 当你看到torch.distributed.DistBackendError: [2] is setting up NCCL communicator and retrieving ncclUniqueId这个错误时,本质上是在说GPU之间的"对讲机"无法正常建立连接。想象一下你正在组织一场多房间的线上会议&…...
管人对账累垮人?巨有科技智慧市集系统一招减负
从城市商圈到景区古镇,从乡村田园到文创园区,各类市集遍地开花,但管理难题始终是制约行业发展的最大瓶颈。人工登记杂乱、对账结算繁琐、现场管控滞后、数据完全空白,一场中型市集就要耗费大量人力物力,大型市集更是纠…...
