设计模式-状态模式
介绍
- 一个对象有状态变化
- 每次状态变化都会触发一个逻辑
- 不能总是用
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扩展的编码,实现功能只需要加一个特…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
