前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >状态机

状态机

作者头像
lonelydawn
发布2021-09-26 11:33:24
5710
发布2021-09-26 11:33:24
举报

这篇文章并不刻意介绍状态机的学术概念,只想谈谈状态机的实际运用。如果想看系统性的学术介绍的话,可以查看百度百科。

百度百科:状态机

应用场景

同学们在工作中,有没有遇到过类似这样的代码。

代码语言:javascript
复制
if (/*  n个判断条件 */) {
    // 200行代码 
} else if (/*  n个判断条件 */)) {
    // 300行代码 
} else if (/*  n个判断条件 */) {
    // 量之大,一屏装不下
} else if (/*  n个判断条件 */) {
    // 量之大,一屏装不下
}
...................

如果安排你去维护这样一段代码,你会怎么做?

是浪费大量时间、枉死无数脑细胞去梳理其中的逻辑关系和方法,顺便抱怨一句“祖传代码真可恶”;还是会采用更好的结构(设计模式)去重构这些充满恶意的代码呢?

状态机模式就是用于处理这样一种复杂的逻辑判断结构的设计模式。

结构分析

在实现状态机时:

  • 一个条件分支可以认为是一种状态(state)。
  • 判断条件成立时(event),则执行对应的方法体(action)。
  • 如果环境变量改变,以致不同分支的判断条件成立,则执行不同分支的方法体,这称为状态转换(transition)。

以上也就是状态机的四大概念:state、event、action、transition。

用法示例

假如业务想要做一个下滑翻屏的 Swiper 页面,每一屏都有不同的内容和动画。为了提高性能,我们希望用户进入该屏时,再播放该屏的动画,此时就可以使用状态机来实现这一场景。

代码语言:javascript
复制
class MovieActionState1 {
	constructor () {}
	update () {
		// Action: 第一屏动画
	}
}

class MovieActionState2 {
	constructor () {}
	update () {
		// Action: 第二屏动画
	}
}

class MovieActionState3 {
	constructor () {}
	update () {
		// Action: 第三屏动画
	}
}

class Movie {
	actionState1; // State:第一屏
	actionState2; // State:第二屏
	actionState3; // State:第三屏

	nowState; // 现态

	constructor () {
		this.actionState1 = new MovieActionState1()
		this.actionState2 = new MovieActionState2()
		this.actionState3 = new MovieActionState3()
		this.nowState = this.actionState1
	}

	run (context) {
		let ctx = context || this // 保证this指向的地址可被访问
		if (ctx.nowState) {
			ctx.nowState.update()
		}
		window.requestAnimationFrame(function () {
			ctx.run(ctx)
		})
	}

	toggleState (index) { // Event
		switch (index) {
			case 0:
				this.nowState = this.actionState1 // Transition
				break;
			case 1: 
				this.nowState = this.actionState2
				break;
			case 2: 
				this.nowState = this.actionState3
				break;
		}
	}
}

测试:

代码语言:javascript
复制
let movie = new Movie()
new Swiper ('.swiper-container', { // 需要引入第三方 Swiper 库
	on: {
		init () {
			movie.run()
		},
		slideChange () {
			movie.toggleState(this.activeIndex)
		}
	}
})

假如此时业务需要再加一屏动画,那么可以创建并实例化一个 MovieActionState4,并在 toggleState 中写上状态的触发条件和转换语句。这种结构清晰易读,要比写个几百上千行的条件分支结构要好维护多了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用场景
  • 结构分析
  • 用法示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档