JavaScript设计模式-状态模式

200 阅读2分钟

状态模式

状态模式: 当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象。

分支语句的弊端

比如一些游戏开发中的人物的移动功能模块,比如移动是有多个方向的,比如上、下、左、右等。此时可能我们会写出这样的代码:

function moveType(type){
  if(type ==='top'){
    console.log('向上移动')
  }else if(type ==='bottom'){
     console.log('向下移动')
  }else if(type ==='left'){
     console.log('向左移动')
  }else if(type ==='right'){
     console.log('向右移动')
  }
}

每一条if语句都代表着一个移动方向,但是如果以后需求需要添加一个向上左移动的需求,那我们还得继续添加if条件判断语句...

对于这种可以减少代码中的条件判断语句,并且使每种判断情况独立存在,而且也更方便管理,有什么方法可以实现呢?没错,就是设计模式中的状态模式每一种条件作为对象内部的一种状态,面对不同判断结果,它其实就是选择对象内的一种状态。

动手实现

const MoveState = function (){
  const Types = {
    top(){
      console.log('top')
    },
    bottom(){
      console.log('bottom')
    },    
    left(){
      console.log('left')
    },
    right(){
      console.log('right')
    }
  }

  function action(type){
    Types[type] && Types[type]()
  }
  return {
    action
  }
}

const move = MoveState()
move.action('left')  
// left

以上这个就展示了状态模式的基本雏形了。对于状态模式,主要目的就是将条件判断的不同结果转化为状态对象的内部状态,既然是状态对象的内部状态,所以一般作为状态对象内部的私有变量,然后给外部提供一个能够调用状态对象内部的接口方法对象。

状态优化

const MoveState = function(){
  // 内部状态的私有变量
  let _currentState = {}
  
  // 移动与状态方法映射
  const Types = {
    top(){
      console.log('top')
    },
    bottom(){
      console.log('bottom')
    },    
    left(){
      console.log('left')
    },
    right(){
      console.log('right')
    }
  }

  // 控制移动对象
  const Actions = {
    changeMoveState(){
      const arg = arguments
      // 重置内部状态
      _currentState = {}
      if(!arg.length) return 
      for(let i = 0; i<arg.length ;i++){
        // 向内部状态中添加动作
        _currentState[arg[i]] = true
      }
      // 返回当前对象,方便链式调用
      return this
    },
    start(){
      console.log('开始移动!')
      for(const k in _currentState){
        // 如果有动作,则移动
       Types[k] && Types[k]()
      }
    }
  }

  return {
    change:Actions.changeMoveState,
    start:Actions.start
  }
}

const move = new MoveState()
move.change('left','top').start()
// 开始移动
// left
// top

总结

状态模式既是解决程序中的雍肿的分支判断语句问题,将每个分支转换为一种状态独立出来,方便每种状态的管理又不至于每次执行时遍历所有分支。在程序中到底产出哪种行为结果,决定选择哪种状态,而选择何种状态又是持续运行时决定的。当然状态模式最终目的即是简化分支判断流程

参考资料

JavaScript设计模式