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
    

特点:

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

目录
相关文章
|
1月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
30 3
|
2月前
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
50 1
|
3月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
3月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
4月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
79 7
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 桥接模式
js设计模式【详解】—— 桥接模式
67 6
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
49 6
|
4月前
|
设计模式 JavaScript 算法
js设计模式【详解】—— 模板方法模式
js设计模式【详解】—— 模板方法模式
47 6
|
4月前
|
设计模式 JavaScript 前端开发
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第7天】在软件工程中,设计模式是解决常见问题的标准解决方案。JavaScript中的工厂模式用于对象创建,但过度使用可能导致抽象过度和缺乏灵活性。单例模式确保唯一实例,但应注意避免全局状态和过度使用。观察者模式实现了一对多依赖,需警惕性能影响和循环依赖。通过理解模式的优缺点,能提升代码质量。例如,工厂模式通过`createShape`函数动态创建对象;单例模式用闭包保证唯一实例;观察者模式让主题对象通知多个观察者。设计模式的恰当运用能增强代码可维护性。
81 0