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 ...
随机推荐
- 在eclipse里用jdbc连接MySQL
进入MySQL控制台, 输入密码, 新建数据库test1并给用户授权,用户名“jaovo”, 创建表,id主键自增, 下载jdbc驱动包(jar文件) 把它放进tomcat的安装目录lib文件夹下(我 ...
- ps入门
目标:把运动截图的日期改掉.一次运动,天天装逼! 1 左上角 文件 -> 打开 选中要P的图片 2 CRTL 和 +号 放大 3 摁住空格键就可以用鼠标拖动图片(把要P的部分放到中间) ...
- python接口自动化测试 - configparser配置文件解析器详细使用
configparser简介 ConfigParser模块已在Python 3中重命名为configparser 该模块定义了ConfigParser类. ConfigParser类实现一种基本的配置 ...
- HGE引擎改进——2014/1/27
2014/1/27 更新 hge库: 1.增加回调函数procResizeFunc(),这个函数会在窗口大小改变时调用,不是必要函数 2.修复LOG信息显示为乱码的错误 项目主页:https://co ...
- python中的dumps和loads区别
一.概念理解 json是一种轻量级的数据交换格式,对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成,如:{"name":"cct ...
- Beta版本
Beta版本 博客说明 这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience 这个作业的要求在哪里 ht ...
- Scala 学习(7)之「trait (1) 」
作为接口使用 在 triat 中可以定义抽象方法,就与抽象类中的抽象方法一样,只要不给出方法的具体实现即可 类可以使用 extends 关键字继承 trait,注意,这里不是 implement,而是 ...
- Static、Final、static final
Static.Final.static final final可以修饰:属性,方法,类,局部变量(方法中的变量) 用final关键字修饰的变量,只能进行一次赋值操作,并且在生存期内不可以改变它的值. ...
- SpringCloud与微服务Ⅲ --- SpringCloud入门概述
一. 什么是SpringCloud SpringCloud基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetF ...
- 脚本在Shell可以执行成功,放到crontab里执行失败
一.背景 自己写了个监控MGR状态的脚本,直接在Linux的Shell环境下可以执行成功,但是只要放到crontab里执行,就失败,脚本内容如下 #!/bin/bash MAIL_ADDR=`cat ...