状态模式

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-12-15

状态模式(State):当一个对象的内部状态发生改变时,会导致其行为的改变。

function Point () {
  this.x = 0;
  this.y = 0;
}

Point.prototype.move = function(direction) {
  if (direction === 'left') {
    this.x--;
  } else if (direction === 'right') {
    this.x++;
  } else if (direction === 'up') {
    this.y++;
  } else if (direction === 'down') {
    this.y--;
  }
  console.log(`当前坐标为 (${this.x}, ${this.y})`)
}

var p = new Point();
p.move('left'); // 当前坐标为 (-1, 0)
p.move('up'); // 当前坐标为 (-1, 1)

但是上面这种写法,如果想做一些复杂的“动作”,比如左上移动就需要调用两次move,亦或者增加if else来处理。

对于状态模式来说,允许对象在内部状态发生改变时改变它的行为,就可以应用在这个场景。

主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

何时使用:代码中包含大量与对象状态有关的条件语句。

如何解决:将各种具体的状态类抽象出来。

function Point () {
  this.x = 0;
  this.y = 0;
  this.state = [];
  this.actions = {
    left() { this.x--; },
    right() { this.x++; },
    up() { this.y++; },
    down() { this.y--; }
  }
}

Point.prototype.changeState = function(state) {
  this.state = state;
  return this;
}

Point.prototype.move = function() {
  this.state.forEach(act => {
    this.actions[act] && this.actions[act].call(this);
  })

  console.log(`当前坐标为 (${this.x}, ${this.y})`)
  return this;
}


var p = new Point();
p.changeState(['left', 'up']).move(); // 当前坐标为 (-1, 1)
p.changeState(['right', 'right']).move(); // 当前坐标为 (1, 1)
p.changeState(['right', 'right', 'up']).move(); // 当前坐标为 (3, 2)

将状态和行为关联起来。将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。