当前位置:   article > 正文

JavaScript 设计模式----状态模式_js状态设计模式

js状态设计模式

1. 状态模式

1.1 状态模式介绍
  • 一个对象有状态变化
  • 每次状态变化都会触发一个逻辑
  • 不能总是用 if...else 来控制
  • 示例
    • 交通信号灯不同颜色的变化
1.2 状态模式类图
  • 传统 UML 类图
    在这里插入图片描述
  • 简化后的 UML 类图
    在这里插入图片描述
1.3 状态模式演示
// 状态(红、黄、绿)
class State {
	constrator(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() {
		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()) // 打印状态

// 黄灯亮了
yellow.handle(context)
console.log(context.getState())

// 红灯亮了
red.handle(context)
console.log(context.getState())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
1.4 状态模式场景
1.4.1 有限状态机
·有限状态机 - 收藏/取消

// 状态机模型
var fsm = new StateMachine({
	init: '收藏', // 初始状态,待收藏
	transitions: [
		{
			name: 'doStore',
			from: '收藏',
			to: '取消收藏'
		},
		{
			name: 'deleteStore',
			from: '取消收藏',
			to: '收藏'
		}
	],
	methods: {
		// 执行收藏
		onDoStore: function () {
			alert('收藏成功') // 可以post请求
			updateText()
		},
		// 取消收藏
		onDeleteStore: function () {
			alert('已取消收藏')
			updateText()
		}
	}
})


var $btn = $('#btn')

// 点击事件
$btn.click(function () {
	if (fsm.is('收藏')) {
		fsm.doStore()
	} else {
		fsm.deleteStore()
	}
})

// 更新文案
function updateText() {
	$btn.text(fsm.state)
}

// 初始化文案
updateText()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
1.4.2 写一个简单的 Promise
  • 回顾 Promise 的语法
function loadImg(src) {
	const promise = new Promise(function (resolve, reject) {
		var img = document.createElement('img')
		img.onload = function () {
			resolve(img)
		}
		img.onerror = function () {
			reject()
		}
		img.src = src
	})
	return promise
}

var src = 'http://www.imooc.com/static/img/index/logo_new.png'
var result = loadImg(src)

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')
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 分析: Promise 就是一个有限状态机
    • Promise 三种状态: pending fulfilled rejected
    • pending -> fulfilled 或者 pending -> rejected
    • 不能逆向变化
// 模型
var fsm = new StateMachine({
	init: 'pending', // 初始化状态
	transitions: [
		{
			name: 'resolve', // 事件名称
			from: 'pending',
			to: 'fullfilled'
		},
		{
			name: 'reject',
			from: 'pending',
			to: 'rejected'
		}
	],
	methods: {
		// 成功 监听 resolve
		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 Promise(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'
let result = loadImg(src)

result.then(function () {
	console.log('ok1')
}, function () {
	console.log('fail1')
})
result.then(function () {
	console.log('ok2')
}, function () {
	console.log('fail2')
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
1.5 状态模式设计原则验证
  • 将状态对象和主题对象分离,状态的变化逻辑单独处理
  • 符合开放封闭原则
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号