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

javascript 中的 UML 类图

class State {
constructor(color) {
this.color = color;
}
handle(context) {
console.log(`turn to ${this.color} light`);
context.setState(this);
}
}
class Context {
constructor() {
this.state = null;
}
setState(state) {
this.state = state;
}
getState() {
return this.state;
}
}
// 测试代码
let context = new Context();
let greed = new State("greed");
let yellow = new State("yellow");
let red = new State("red");
// 绿灯亮了
greed.handle(context);
console.log(context.getState());
// 黄灯亮了
yellow.handle(context);
console.log(context.getState());
// 红灯亮了
red.handle(context);
console.log(context.getState());
应用场景
有限状态机
- 有限个状态,以及在这些状态之间的变化
- 交通信号灯
- 利用开源的 lib:JavaScript-state-machine
- javascript-state-machine
- 运行
npm install javascript-state-machine --save
有限状态机的收藏与取消
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<p>有限状态机</p>
<button id="btn"></button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="./03-javascript-state-machine.js"></script>
<script>
// 状态机模型
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(1);
} else {
fsm.deleteStore();
}
});
// 更新文案
function updateText() {
$btn.text(fsm.state);
}
// 初始化文案
updateText();
</script>
</body>
</html>
写一个简单的 promise
- promise 就是一个有限自动机
- promise 三种状态:pending fullfilled rejected
- pending -> fullfilled 或者 pending -> rejected
- 不能逆向变化
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="./03-javascript-state-machine.js"></script>
<script>
// 模型
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 {
constructor(fn) {
this.successList = [];
this.failList = [];
fn(
() => {
// resolve 函数
fsm.resolve(this);
},
() => {
// reject 函数
fsm.reject(this);
}
);
}
then(successFn, failFn) {
this.successList.push(successFn);
this.failList.push(failFn);
}
}
// 测试代码
function loadImg(src) {
const promise = new MyPromise(function(resolve, reject) {
var img = document.createElement("img");
img.onload = function() {
resolve(img);
};
img.onerror = function() {
reject();
};
img.src = src;
});
return promise;
}
var src = "https://blog-static.cnblogs.com/files/ygjzs/images.gif";
var result = loadImg(src);
console.log(result);
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");
}
);
</script>
</body>
</html>
设计原则验证
- 将状态对象和主题对象分离,状态的变化逻辑单独处理
- 符合开放封闭原则
JavaScript-状态模式的更多相关文章
- 轻松掌握:JavaScript状态模式
状态模式 状态模式(State)允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类. 状态模式的使用场景也特别明确,有如下两点: 一个对象的行为取决于它的状态,并且它必须在运行 ...
- JavaScript状态模式及状态机模型
这是一篇,我自己都看不完的文章... 文章大体就两部分: 状态模式的介绍 状态机模型的函数库javascript-state-machine的用法和源码解析 场景及问题背景: 我们平时开发时本质上就是 ...
- javascript - 状态模式 - 简化分支判断流程
状态模式笔记 当一个对象的内部状态发生改变时,会导致行为的改变,这像是改变了对象 状态模式既是解决程序中臃肿的分支判断语句问题,将每个分支转化为一种状态独立出来,方便每种状态的管理又不至于每次 ...
- Javascript设计模式之我见:状态模式
大家好!本文介绍状态模式及其在Javascript中的应用. 模式介绍 定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是控制一个对象状态的条件表达式 ...
- javascript设计模式学习之十六——状态模式
一.状态模式的定义 状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模 ...
- 再起航,我的学习笔记之JavaScript设计模式19(状态模式)
状态模式 概念介绍 状态模式(State):当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象 示例演示 在我们写项目的过程中或多或少会遇到如下的多分支判断 function ...
- JavaScript设计模式 - 状态模式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 深入理解JavaScript系列(43):设计模式之状态模式
介绍 状态模式(State)允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类. 正文 举个例子,就比如我们平时在下载东西,通常就会有好几个状态,比如准备状态(ReadySta ...
- JavaScript设计模式——状态模式
状态和行为: 所谓对象的状态,通常指的就是对象实例的属性的值:而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上. 状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应 ...
- javascript设计模式--状态模式(State)
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- [题解]CSP2019 Solution - Part B
\(\text{orz}\) 一波现场 \(\text{A}\) 掉 \(\text{D1T3}\) 的神仙 D2T3 centroid Solution 考虑每个点 \(u\) 作为重心的贡献 假设 ...
- 遗传编程GP-地图路径寻路
本文介绍的是基于GP,并非A*算法,算是另类实现吧. 先看看地图定义,在文本文件中定义如下字符串,代表30列11行大小的地图 初始位置在左上角(0,0) ,值为1的是允许走的通的路,目标位置为右下角( ...
- .net core 连接数据库(通过数据库生成Modell)
创建数据库 (扫盲贴还劳烦大神们勿喷,谢谢) 打开数据库 输入如下代码 创建数据库 CREATE DATABASE [Blogging]; GO USE [Blogging]; GO CREATE T ...
- python接口自动化测试 - unittest框架suite、runner详细使用
test suite 测试套件,理解成测试用例集 一系列的测试用例,或测试套件,理解成测试用例的集合和测试套件的集合 当运行测试套件时,则运行里面添加的所有测试用例 test runner 测试运行器 ...
- 揭秘webpack loader
前言 Loader(加载器) 是 webpack 的核心之一.它用于将不同类型的文件转换为 webpack 可识别的模块.本文将尝试深入探索 webpack 中的 loader,揭秘它的工作原理,以及 ...
- 贪心+huffman编码+模拟退火+分治(一)
(一)贪心 1.A - 今年暑假不AC “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很 ...
- AI初探1
一个典型的机器学习的过程,首先给出一个输入数据,我们的算法会通过一系列的过程得到一个估计的函数,这个函数有能力对没有见过的新数据给出一个新的估计,也被称为构建一个模型.就如同上面的线性回归函数. 在机 ...
- redis端口6379的由来
有一个技巧,Redis端口号6379,是手机键盘上的MERZ.
- V8垃圾回收?看这篇就够了!
什么是内存管理 内存管理是控制和协调应用程序访问电脑内存的过程.这个过程是复杂的,对于我们来说,可以说相当于一个黑匣子. 当咱们的应用程序运行在某个操作系统中的时候,它访问电脑内存(RAM)来达成下列 ...
- SMB信息泄露
开门见山 1. 用netdiscover -r 扫描与攻击机同一网段的靶机,发现PCS 2. 扫描靶场开放信息 3. 挖掘靶场全部信息 4. 针对SMB协议,使用空口令,若口令尝试登录,并查看敏感文件 ...