笔记设计模式5提高代码质量

9次阅读

共计 2597 个字符,预计需要花费 7 分钟才能阅读完成。

策略模式 / 状态模式

  • 目的:优化 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);
      }
    }
正文完
 0