策略模式/状态模式

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