状态模式(State)容许一个对象在其内部状态改变的时候改变它的行为,对象看起来彷佛修改了它的类。
其实就是用一个对象或者数组记录一组状态,每一个状态对应一个实现,实现的时候根据状态挨个去运行实现。html
好比超级玛丽,就可能同时有好几个状态好比 跳跃,移动,射击,蹲下 等,若是对这些动做一个个进行处理判断,须要多个if-else
或者switch
不只丑陋不说,并且在遇到有组合动做的时候,实现就会变的更为复杂,这里可使用状态模式来实现。前端
状态模式的思路是:首先建立一个状态对象或者数组,内部保存状态变量,而后内部封装好每种动做对应的状态,而后状态对象返回一个接口对象,它能够对内部的状态修改或者调用。segmentfault
const SuperMarry = (function() { let _currentState = [], // 状态数组 states = { jump() {console.log('跳跃!')}, move() {console.log('移动!')}, shoot() {console.log('射击!')}, squat() {console.log('蹲下!')} } const Action = { changeState(arr) { // 更改当前动做 _currentState = arr return this }, goes() { console.log('触发动做') _currentState.forEach(T => states[T] && states[T]()) return this } } return { change: Action.changeState, go: Action.goes } })() SuperMarry .change(['jump', 'shoot']) .go() // 触发动做 跳跃! 射击! .go() // 触发动做 跳跃! 射击! .change(['squat']) .go() // 触发动做 蹲下!
这里可使用ES6
的class
优化一下:设计模式
class SuperMarry { constructor() { this._currentState = [] this.states = { jump() {console.log('跳跃!')}, move() {console.log('移动!')}, shoot() {console.log('射击!')}, squat() {console.log('蹲下!')} } } change(arr) { // 更改当前动做 this._currentState = arr return this } go() { console.log('触发动做') this._currentState.forEach(T => this.states[T] && this.states[T]()) return this } } new SuperMarry() .change(['jump', 'shoot']) .go() // 触发动做 跳跃! 射击! .go() // 触发动做 跳跃! 射击! .change(['squat']) .go() // 触发动做 蹲下!
状态模式的使用场景也特别明确,有以下两点:数组
简而言之,当遇到不少同级if-else
或者switch
的时候,可使用状态模式来进行简化。缓存
本文是系列文章,能够相互参考印证,共同进步~微信
网上的帖子大多深浅不一,甚至有些先后矛盾,在下的文章都是学习过程当中的总结,若是发现错误,欢迎留言指出~函数
参考:
《Javascript 设计模式》 - 张荣铭
设计模式之状态模式
PS:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~学习
另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~优化