Javascript 設計模式系統講解與應用——學習筆記10-狀態模式
狀態模式
- 一個物件有狀態變化
- 每次狀態變化都會觸發一個邏輯
- 不能總是用
if ... else
來控制
示例
交通紅綠燈
傳統UML類圖
JS版簡單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
}
getState() {
return this.state
}
setState(state) {
this.state = state
}
}
// test
let context = new Context()
let green = new State('green')
let yellow = new State('yellow')
let red = new State('red')
// 綠燈亮了
green.handle(context)
console.log(context.getState()) // 列印狀態
// 紅燈亮了
red.handle(context)
console.log(context.getState()) // 列印狀態
// 黃燈亮了
yellow.handle(context)
console.log(context.getState()) // 列印狀態
輸出:
turn to green light
State { color: 'green' }
turn to red light
State { color: 'red' }
turn to yellow light
State { color: 'yellow' }
場景
- 有限狀態機
- 寫一個簡單的Promise
有限狀態機
- 有限個狀態,以及在這些狀態之間的變化
- 如交通訊號燈
- 使用開源lib: javascript-state-machine
https://github.com/jakesgordon/javascript-state-machine
// 狀態機模型
const fsm = new StateMachine({
init: '收藏', // 初始狀態,待收藏
transitions: [
{
name: 'doState',
from: '收藏',
to: '取消收藏'
},
{
name: 'deleteStore',
from: '取消收藏',
to: '收藏'
}
],
methods: {
// 監聽執行收藏
onDoStore: function() {
alert('收藏成功') // 可以放post請求
updateText()
},
// 監聽取消收藏
onDeleteStore: function() {
alert('已取消收藏') // 可以放post請求
updateText()
}
}
})
const $btn = ${'#btn'}
// 點選事件
$btn.click(function () {
if (fsm.is('收藏')) {
fsm.doStore()
} else {
fsm.deleteStore()
}
})
// 更新文案
funciton updateText() {
$btn.text(fsm.state)
}
// 初始化文案
updateText()
寫一個簡單的Promise
Promise就是有限狀態機
- Promise三種狀態: pending fullfilled rejected
- pending -> fullfilled 或者 pending -> rejected
- 不能逆向變化
// 模型
const 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)
}
}
// test
function loadImg(src) {
const promise = new MyPromise(function(resolve, reject) {
let img = document.createElement('img')
img.onload = function () {
resolve(img)
}
img.onerror = function () {
reject()
}
img.src = src
})
return promise
}
let src = "xxx.png"
let result = loadImg(src)
result.then(function () {
console.log('ok1')
}, function () {
console.log('fail1')
})
result.then(function () {
console.log('ok2')
}, function () {
console.log('fail2')
})
設計原則驗證
- 將狀態物件和主題物件分離,狀態的變化邏輯單獨處理
- 符合開放封閉原則
相關文章
- 設計模式學習筆記之狀態模式設計模式筆記
- 設計模式學習筆記(二十)狀態模式及其實現設計模式筆記
- JavaScript設計模式學習筆記JavaScript設計模式筆記
- javascript設計模式狀態模式JavaScript設計模式
- 設計模式學習筆記(九)橋接模式及其應用設計模式筆記橋接
- 設計模式學習筆記(十二)享元模式及其應用設計模式筆記
- 設計模式第八講-狀態模式設計模式
- 設計模式學習筆記(十)裝飾器模式及其應用設計模式筆記
- 學習筆記-設計模式:MVC模式筆記設計模式MVC
- javascript設計模式與應用JavaScript設計模式
- 設計模式學習筆記(十七)中介者模式及其應用場景設計模式筆記
- 設計模式學習筆記(十九)觀察者模式及應用場景設計模式筆記
- 《JavaScript設計模式與開發實踐》模式篇(13)—— 狀態模式JavaScript設計模式
- 設計模式學習筆記設計模式筆記
- 學習筆記-設計模式筆記設計模式
- 設計模式學習筆記——單例模式設計模式筆記單例
- 設計模式學習筆記之策略模式設計模式筆記
- 設計模式學習筆記(八)介面卡模式介紹及其應用設計模式筆記
- 我學設計模式 之 狀態模式設計模式
- 軟體設計模式學習(二十四)狀態模式設計模式
- Java設計模式學習筆記——工廠模式與抽象工廠模式Java設計模式筆記抽象
- Java設計模式學習筆記(一) 設計模式概述Java設計模式筆記
- 設計模式-狀態模式設計模式
- 設計模式:狀態模式設計模式
- php設計模式學習筆記PHP設計模式筆記
- 設計模式學習筆記之工廠模式設計模式筆記
- 設計模式學習筆記之迭代器模式設計模式筆記
- 設計模式學習筆記之單例模式設計模式筆記單例
- 設計模式學習筆記(十六)迭代器模式及其在Java 容器中的應用設計模式筆記Java
- 設計模式(十五)狀態模式設計模式
- 設計模式之——狀態模式設計模式
- 設計模式(六):狀態模式設計模式
- Java設計模式學習筆記(五) 單例模式Java設計模式筆記單例
- 設計模式學習筆記之裝飾者模式設計模式筆記
- 設計模式學習筆記之介面卡模式設計模式筆記
- javascript設計模式(張容銘)學習筆記 – 外觀模式繫結事件JavaScript設計模式筆記事件
- 用設計模式去掉沒必要的狀態變數 —— 狀態模式設計模式變數
- Event Bus 設計模式學習筆記設計模式筆記