状态模式

一个对象有状态变化

每次状态变化都会触发一个逻辑

不能总是用 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-状态模式的更多相关文章

  1. 轻松掌握:JavaScript状态模式

    状态模式 状态模式(State)允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类. 状态模式的使用场景也特别明确,有如下两点: 一个对象的行为取决于它的状态,并且它必须在运行 ...

  2. JavaScript状态模式及状态机模型

    这是一篇,我自己都看不完的文章... 文章大体就两部分: 状态模式的介绍 状态机模型的函数库javascript-state-machine的用法和源码解析 场景及问题背景: 我们平时开发时本质上就是 ...

  3. javascript - 状态模式 - 简化分支判断流程

    状态模式笔记   当一个对象的内部状态发生改变时,会导致行为的改变,这像是改变了对象   状态模式既是解决程序中臃肿的分支判断语句问题,将每个分支转化为一种状态独立出来,方便每种状态的管理又不至于每次 ...

  4. Javascript设计模式之我见:状态模式

    大家好!本文介绍状态模式及其在Javascript中的应用. 模式介绍 定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是控制一个对象状态的条件表达式 ...

  5. javascript设计模式学习之十六——状态模式

    一.状态模式的定义 状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模 ...

  6. 再起航,我的学习笔记之JavaScript设计模式19(状态模式)

    状态模式 概念介绍 状态模式(State):当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象 示例演示 在我们写项目的过程中或多或少会遇到如下的多分支判断 function ...

  7. JavaScript设计模式 - 状态模式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 深入理解JavaScript系列(43):设计模式之状态模式

    介绍 状态模式(State)允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类. 正文 举个例子,就比如我们平时在下载东西,通常就会有好几个状态,比如准备状态(ReadySta ...

  9. JavaScript设计模式——状态模式

    状态和行为: 所谓对象的状态,通常指的就是对象实例的属性的值:而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上. 状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应 ...

  10. javascript设计模式--状态模式(State)

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. Tomcat9乱码解决

    在tomcat的解压目录下找到conf,打开进入,logging.properties文件,在该文件中,修改 java.util.logging.ConsoleHandler.encoding = U ...

  2. 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战

    之前在一家公司里用过Knockout,是easyui 和 Knockout结合 的.下面的这本应该不错. 目录 前言 第一部分入门指南 第1章MVC介绍 创建第一个项目 分析HomeControlle ...

  3. PPT制作简易套路指南

    最近正在重做公众号相关的一些设计以及排版,想到年前部门里的UI设计大神做了一个关于"PPT设计指南"的分享,正好可以拿来实践一把. 一直以来,PPT.Word.Excel都是办公人 ...

  4. Python3.6在win7中无法正常运行的问题

    Python3.6在启动时报缺少api-ms-win-crt-runtime-l1-1-0.dll解决靠谱方法:1.到正常的机器,或者就在开发环境,去搜索api-ms-win-crt-runtime- ...

  5. Spring Boot动态注入删除bean

    Spring Boot动态注入删除bean 概述 因为如果采用配置文件或者注解,我们要加入对象的话,还要重启服务,如果我们想要避免这一情况就得采用动态处理bean,包括:动态注入,动态删除. 动态注入 ...

  6. Kafka系列1:Kafka概况

    Kafka系列1:Kafka概况 Kafka是当前分布式系统中最流行的消息中间件之一,凭借着其高吞吐量的设计,在日志收集系统和消息系统的应用场景中深得开发者喜爱.本篇就聊聊Kafka相关的一些知识点. ...

  7. 对比PXC集群与主从架构在一致性上的区别

    在上一篇文章中,已经完成了三节点PXC集群的搭建,现在搭建node3的从库node4,并且有如下测试: 搭建node3的从库,代号node4 测试1: 先断开node3节点,然后在node1构造数据, ...

  8. MCMC&Gibbs sampling

    Note of Markov Chain Monte Carlo and Gibbs Sampling :  http://pan.baidu.com/s/1jHpWY1o 序:A major lim ...

  9. artTemplate--模板使用自定义函数(2)

    我的常用自定义函数 <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> < ...

  10. java枚举类的常见用法

    枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似.不过相比 ...