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 ...
随机推荐
- JPA基本注解的使用
一:JPA基本注解 使用: 使用: 使用: 查看表: 二:用table来生成主键 使用: allocationSize:每次增加多少 tablel:指定使用那张表 执行两次main方法后查看表: jp ...
- php--->依赖注入(DI)实现控制反转(IOC)
依赖注入(DI)实现控制反转(IOC) DI和IOC概念理解 当一个类的实例需要另一个类的实例协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例.而采用依赖注入的方式,创建被调用者的工作 ...
- Java框架-MyBatis三剑客之MyBatis Generator(mybatis-generator MBG插件)详解
生成器设计思路: 连接数据库 -> 获取表结构 -> 生成文件 1 下载与安装 官网文档入口 最方便的 maven 插件使用方式 贴至pom 文件 2 新建配置文件 填充配置信息(官网示例 ...
- 这个菜鸟花几个小时写的 DEMO 被码云推荐上首页 ?
写在最前 没有接触过 AntV 的诸位看客可通过这篇不成文的文章稍作了解.最近 病毒猖獗,遂抽空做了一个相关小 DEMO.数据可视化方面的使用的是 AntV F2,前端框架使用 Vue 快速成 ...
- Ubuntu 入门笔记(1)
在阿里云上申请了一个云服务器,开始学习Linux.我选择的是Ubuntu 14.04 ,在登录时就绕了我好长时间,输入用户名是有显示的,但是输入密码就没有反应了,查找了之后才发现原来这是Ubuntu ...
- react 获取input的值 ref 和 this.setState({})
1.ref //class my_filter(reg){ const inpVal = this.input.value; console.log(inpVal) ...
- 机器学习-NLP之Word embedding 原理及应用
概述 自然语言是非常复杂多变的,计算机也不认识咱们的语言,那么咱们如何让咱们的计算机学习咱们的语言呢?首先肯定得对咱们的所有文字进行编码吧,那咱们很多小伙伴肯定立马就想出了这还不简单嘛,咱们的计算机不 ...
- Druid入门(1)—— 快速入门实时分析利器-Druid_0.17
一.安装准备 本次安装的版本是截止2020.1.30最新的版本0.17.0 软件要求 需要Java 8(8u92 +)以上的版本,否则会有问题 Linux,Mac OS X或其他类似Unix的操作系统 ...
- 红帽RedHat 8.0新特性(网络、yum源、Web界面管理等)
1.Red Hat8 配置静态IP 注意:Red Hat8网络管理默认使用NetworkManager,而不是之前版本的network. 按照之前版本我们一般通过配置文件设置静态IP地址信息,如下: ...
- Grevl旅游注册的初步界面,以源代码和运行图片展示
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...