3

策略模式/状态模式

  • 目的:优化if-else分支
  • 应用场景:当代码if-else分支过多时
  • 基本结构

    // 计算器,将if判断用策略模式改写
    function calculator(type, a, b) {
      var strategy = {
        add(a, b) {
          return a + b
        },
        minus(a, b) {
          return a - b
        },
        division(a, b) {
          return a / b
        }
      }
      return strategy[type](a, b)
    }
    // 状态模式
    function stateFactor (state) {
      var stateObject = {
        _status: '',
        state: {
          state1 () {},
          state2 () {}
        },
        run () {
          return this.state[this._status]()
        }
      }
      stateObject._status = state
      return stateObject
    }
    stateFactor('state1').run()
  • 例:复合运动

    function moveLeft() {
        console.log('left')
    }
    function moveRight() {
        console.log('right')
    }
    function moveTop() {
        console.log('top')
    }
    function moveBottom() {
        console.log('bottom')
    }
    function move() {
        this.status = [];
        this.actionHandle = {
            left: moveLeft,
            right: moveRight,
            top: moveTop,
            bottom: moveBottom
        }
    }
    move.prototype.run = function () {
        // 将arguments变成真数组
        this.status = Array.prototype.slice.call(arguments);
        this.status.forEach((action) => {
            this.actionHandle[action]();
        })
    }
    new move().run('left', 'right');

外观模式

  • 目的:给多个复杂的子系统提供一个一致的接口
  • 应用场景:完成一个操作需要操作多个子系统
  • 基本结构

      function Model1 () {}
      function Model2 () {}
      function use() {
        Model2(Model1())
      }

迭代器模式

  • 目的:不访问内部的情况下,方便的遍历数据
  • 应用场景:操作某个对象,不能暴露内部时
  • 基本结构 forEach

    function Iterator(data) {
      this.data = data;
    }
    Iterator.prototype.dealEach = function (fn) {
      if (this.data instanceof Array) {
        // 数组
        for (var i = 0; i < this.data.length; i++) {
          fn(this.data[i], i)
        }
      } else {
        // 对象
        for (var item in this.data) {
          fn(this.data[item], item)
        }
      }
    }
  • 例:封装一个筛选数据的方法

      var data = [{ num: 1 }, { num: 2 }, { num: 3 }]
      function getData(data) {
        function Iterator(data) {
          this.data = data;
        }
        Iterator.prototype.hasSomeData = function (handler, num) {
          var _arr = [];
          var handleFn;
          if (typeof handler == 'function') {
            handleFn = handler;
          } else {
            handleFn = function (item) {
              if (item[handler] == num) {
                return item;
              }
            }
          }
          for (var i = 0; i < this.data.length; i++) {
            var _result = handleFn.call(this, this.data[i])
            if (_result) {
              _arr.push(_result);
            }
    
          }
          return _arr;
        }
        return new Iterator(data);
      }
      // 传入属性和值,检测有没有num值为1的数据
      // let r = getData(data).hasSomeData('num', 1);
      // 传入函数,检测有没有通过函数检测的数据
      let r = getData(data).hasSomeData(function (item) {
        if (item.num - 1 == 2) {
          return item;
        }
      });
      console.log(r)

备忘录模式

  • 目的:记录状态,方便回滚
  • 应用场景:系统状态多样,需要回滚状态
  • 基本结构

      function memento () {
        var cache = {}
        return function (cacheName) {
          if (cache[cacheName]) {
            // 有缓存
          } else {
            // 没有缓存
          }
        }
      }
      var mementoFn = memento()
      mementoFn('xxx')
  • 例:前进后退功能

    function moveDiv() {
      this.stateList = []; // 存储状态
      this.nowState = 0; // 当前状态
    }
    moveDiv.prototype.move = function (type, num) {
      moveDiv(type, num);
      this.stateList.push({
        type: type,
        num: num
      });
      this.nowState = this.stateList.length - 1;
    }
    moveDiv.prototype.go = function () {
      var _state;
      if (this.nowState < this.stateList.length - 1) {
        this.nowState++;
        _state = this.stateList[this.nowState];
        moveDiv(_state.type, _state.num);
      }
    }
    moveDiv.prototype.back = function () {
      var _state;
      if (this.nowState >= 0) {
        this.nowState--;
        _state = this.stateList[this.nowState];
        moveDiv(_state.type, _state.num);
      }
    }

CSep27
37 声望1 粉丝

学习中...整理中...