狀態模式
一個物件有狀態變化
每次狀態變化都會觸發一個邏輯
不能總是用 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://www.cnblogs.com/ygjzs/p/"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>
