JavaScript设计模式(十七):超级玛丽-状态模式

简介: 超级玛丽-状态模式

状态模式(State)

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

主要目的就是将条件判断的不同结果转化为状态对象的内部状态。

解决多分支判断问题

  • 一般判断形势 (当新增需求时那么就需要添加新的判断条件)

      // 展示结果
      function showResult(state) {
         
          if (state == 0) {
         
              // 处理结果0
              console.log('这是第一种情况');
          } else if (state == 1) {
         
              // 处理结果1
              console.log('这是第二种情况');
          } else if (state == 2) {
         
              // 处理结果2
              console.log('这是第三种情况');
          } else if (state == 3) {
         
              // 处理结果3
              console.log('这是第四种情况');
          }
      }
    
      showResult(2); // 这是第三种情况
    
  • 状态对象的实现 (状态模式的基本雏形)

      // 投票结果状态对象
      const ResutlState = (function () {
         
          // 判断结果保存在内部状态中
          var State = {
         
              // 每种状态作为一种独立方法保存
              state0: function () {
         
                  // 处理结果0
                  console.log('这是第一种情况');
              },
              state1: function () {
         
                  // 处理结果1
                  console.log('这是第二种情况');
              },
              state2: function () {
         
                  // 处理结果2
                  console.log('这是第三种情况');
              },
              state3: function () {
         
                  // 处理结果3
                  console.log('这是第四种情况');
              }
          };
          // 获取某一种状态并执行其对应的方法
          function show(type) {
         
              State[`state${type}`] && State[`state${type}`]();
          }
          return {
         
              // 返回调用状态方法接口
              show
          }
      }());
    
      ResutlState.show(2); // 这是第三种情况
    

超级玛丽示例:

  • if ... else ...形势判断角色动作:
      // 单动作条件判断 每增加一个动作就需要添加一个判断
      function playerController(state) {
         
          if (state === 'move') {
         
              console.log('移动');
          } else if (state === 'jump') {
         
              console.log('跳跃');
          } else {
         
              console.log('idle');
          }
      }
      // 复合动作对条件判断的开销是翻倍的
      function playerController(state1, state2) {
         
          if (state1 === 'move') {
         
              console.log('移动');
          } else if (state1 === 'move' && state2 === 'shoot') {
         
              console.log('移动射击');
          } else if (state1 === 'jump') {
         
              console.log('跳跃');
          } else if (state1 === 'jump' && state2 === 'shoot') {
         
              console.log('跳跃射击');
          } else if (state1 === 'idle' && state2 === 'shoot') {
         
              console.log('站立射击');
          } else {
         
              console.log('idle');
          }
      }
    
  • 状态优化形势:

      // 创建超级玛丽状态类
      const Player = function () {
         
    
          // 内部状态私有变量(缓存当前状态)
          let _currentState = [];
    
          // 动作与状态方法映射
          const state = {
         
              // 跳跃
              jump() {
          console.log('jump'); },
              // 移动
              move() {
          console.log('move'); },
              // 射击
              shoot() {
          console.log('shoot'); },
              // 蹲下
              squat() {
          console.log('squat'); }
          };
    
          // 动作控制类,返回接口方法 changeState、action
          return {
         
              // 改变状态方法 - 组合动作通过传递多个参数实现
              changeState(...args) {
         
                  // 重置并向内部状态中添加动作
                  _currentState = args;
                  // 返回动作控制类
                  return this;
              },
              // 执行动作
              action() {
         
                  console.log('触发一次动作');
                  // 遍历内部状态保存的动作 - 如果该动作存在则执行
                  _currentState.forEach(key => state[key] && state[key]())
                  return this;
              }
          };
      };
    
      // 创建一个超级玛丽
      const player = new Player();
      player
          .changeState('jump', 'shoot')       // 改变为`跳跃`与`射击`动作组合
          .action()                           // 执行动作             触发一次动作 ---> jump - shoot
          .action()                           // 执行动作             触发一次动作 ---> jump - shoot
          .changeState('shoot')               // 改变为`射击`动作
          .action();                          // 执行动作             触发一次动作 ---> shoot
    

特点:

状态模式既是 解决程序中臃肿的分支判断语句问题,将 每个分支转化为一种 状态 独立出来方便 每种 状态管理不至于每次执行时遍历所有分支

目录
相关文章
|
4天前
|
设计模式 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 设计模式与实战应用
【4月更文挑战第30天】本文探讨JavaScript设计模式在提升开发效率和代码质量中的关键作用。涵盖单例、工厂、观察者、装饰器和策略模式,并通过实例阐述其在全局状态管理、复杂对象创建、实时数据更新、功能扩展和算法切换的应用。理解并运用这些模式能帮助开发者应对复杂项目,提升前端开发能力。
|
4天前
|
设计模式 前端开发 算法
【面试题】 ES6 类聊 JavaScript 设计模式之行为型模式(二)
【面试题】 ES6 类聊 JavaScript 设计模式之行为型模式(二)
|
3天前
|
设计模式 存储 前端开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
|
4天前
|
设计模式 JavaScript 前端开发
js设计模式-观察者模式与发布/订阅模式
观察者模式和发布/订阅模式是JavaScript中的两种设计模式,用于处理对象间的通信和事件处理。观察者模式中,一个主题对象状态改变会通知所有观察者。实现包括定义主题和观察者对象,以及在主题中添加、删除和通知观察者的功能。发布/订阅模式则引入事件管理器,允许发布者发布事件,订阅者通过订阅接收通知。
|
4天前
|
设计模式 JavaScript 算法
js设计模式-策略模式与代理模式的应用
策略模式和代理模式是JavaScript常用设计模式。策略模式通过封装一系列算法,使它们可互换,让算法独立于客户端,提供灵活的选择。例如,定义不同计算策略并用Context类执行。代理模式则为对象提供代理以控制访问,常用于延迟加载或权限控制。如创建RealSubject和Proxy类,Proxy在调用RealSubject方法前可执行额外操作。这两种模式在复杂业务逻辑中发挥重要作用,根据需求选择合适模式解决问题。
|
4天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
4天前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
30 4
|
4天前
|
设计模式 缓存 JavaScript
js常用设计模式
js常用设计模式
25 1
|
4天前
|
设计模式
【设计模式】状态模式
【设计模式】状态模式
|
4天前
|
设计模式 Java 测试技术
浅谈设计模式 - 状态模式(十三)
浅谈设计模式 - 状态模式(十三)
19 0