#状态模式

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类

通过状态的切换来切换逻辑

比如根据状态调制咖啡

const stateToProcessor = {
  american() {
    console.log('我只吐黑咖啡')
  },
  latte() {
    this.american()
    console.log('加点奶')
  },
  vanillaLatte() {
    this.latte()
    console.log('再加香草糖浆')
  },
}

class CoffeeMaker {
  constructor() {
    /**
    这里略去咖啡机中与咖啡状态切换无关的一些初始化逻辑
  **/
    // 初始化状态,没有切换任何咖啡模式
    this.state = 'init'
  }

  // 关注咖啡机状态切换函数
  changeState(state) {
    // 记录当前状态
    this.state = state
    // 若状态不存在,则返回
    if (!stateToProcessor[state]) {
      return
    }
    stateToProcessor[state]()
  }
}

const mk = new CoffeeMaker()
mk.changeState('latte')

但是 stateToProcessor 里的工序函数,感知不到咖啡机的内部状况

这个状况才是状态

上述只是实现了没有状态的逻辑,主要运用的还是只是策略模式

程序不止是不相干的逻辑

class CoffeeMaker {
  constructor() {
    /**
    这里略去咖啡机中与咖啡状态切换无关的一些初始化逻辑
  **/
    // 初始化状态,没有切换任何咖啡模式
    this.state = 'init'
    // 初始化牛奶的存储量
    this.leftMilk = 500
  }

  stateToProcessor = {
    that: this,
    american() {
      // 尝试在行为函数里拿到咖啡机实例的信息并输出
      console.log('咖啡机现在的牛奶存储量是:', this.that.leftMilk, 'ml')
      console.log('我只吐黑咖啡')
    },
    latte() {
      this.american()
      this.that.leftMilk -= 100
      console.log('加100ml奶')
      console.log('咖啡机现在的牛奶存储量是:', this.that.leftMilk, 'ml')
    },
    vanillaLatte() {
      this.latte()
      console.log('再加香草糖浆')
    },
  }

  // 关注咖啡机状态切换函数
  changeState(state) {
    this.state = state
    if (!this.stateToProcessor[state]) {
      return
    }
    this.stateToProcessor[state]()
  }
}

const mk = new CoffeeMaker()
mk.changeState('latte')

#小结

状态模式是对状态-逻辑的封装,运行时对不同状态选用不同逻辑

和策略模式很像,但是区别正是状态,策略模式侧重使用映射对象时选择逻辑,状态模式侧重运行时对象根据状态改变逻辑