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 ...
随机推荐
- python面向对象(一切皆对象)
使用面向对象的思想设计一个乌龟的角色: 表面特征:绿色.有4条腿.重10kg.有外壳等等 行为特征:爬.吃.睡觉.将头和四肢缩到壳里等等 class tortoise: bodycolor = &qu ...
- 高通量计算框架HTCondor(五)——分布计算
目录 1. 正文 1.1. 任务描述文件 1.2. 提交任务 1.3. 返回结果 2. 相关 1. 正文 1.1. 任务描述文件 前文提到过,HTCondor是通过condor_submit命令将提交 ...
- AVL练习题——宠物收养所
题目描述 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出 ...
- 用JAVA分别实现WebSocket客户端与服务端
最近公司在搞一个项目刚好需要用到WebSocket技术来实现实时数据的传输,因为之前也没接触过,所以捣鼓了好些天,最近恰巧有空就写写.有误的地方还请大牛们能及时指正. 项目背景:基于spring+sp ...
- Java容器解析系列(11) HashMap 详解
本篇我们来介绍一个最常用的Map结构--HashMap 关于HashMap,关于其基本原理,网上对其进行讲解的博客非常多,且很多都写的比较好,所以.... 这里直接贴上地址: 关于hash算法: Ha ...
- Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析
前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘. 本篇我们将介绍redis的最后一种数据类型: zset 的相关实现. ...
- php--->注册模式
注册模式 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法. 优点:单例模式解决的是如何在整个项目中 ...
- STVP编译时遇到no default placement for segment .FLASH_CODE
最近编译STM8S003时需要使用flash库函数,看起来简单,实则折腾了超过1天.今天总结方法如下: 1.修改stm8s.h 156行 #define RAM_EXECUTION 注释去掉 如 ...
- python中os模块的一些小总结
(一)os模块的应用小总结 os.name: 获取当前系统平台,Windows下返回'nt',Linux下返回'posix'. os.linesep: 获取当前平台使用的行终止符.Windows下 ...
- ThreadLocal源码分析-黄金分割数的使用
前提 最近接触到的一个项目要兼容新老系统,最终采用了ThreadLocal(实际上用的是InheritableThreadLocal)用于在子线程获取父线程中共享的变量.问题是解决了,但是后来发现对T ...