js设计模式——状态模式

416 阅读2分钟

状态模式主要解决了什么?

状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

咖啡引发的状态模式

楼下咖啡店打折了,9.9一杯,抱着‘有便宜不占就是吃亏’的心态,我快步来到咖啡店,引入眼帘的咖啡种类让我难以抉择,这时产品经理阿黄也来了,阿黄一见到我,本着一天不提需求浑身难受的理念,对我说:听说你们程序员是万能的,你能设计一个咖啡机的程序吗?

我心想:“你怕是有点XX小问题!”

作为多年的ifelse玩家,开始输出代码了:

class CoffeeMaker {
  constructor(state) {
    this.state = state
  }
  coffeeProcess() {
    if (this.state === 'american') {
      console.log('我只吐黑咖啡');
    } else if (this.state === 'latte') {
      console.log('我只吐黑咖啡加点奶');
    } else if (this.state === 'vanillaLatte') {
      console.log('我只吐黑咖啡加点奶再加香草糖浆');
    } else {
      console.log('我只吐黑咖啡加点奶再加巧克力');
    }
  }
}
const coffeeMakerInstance = new CoffeeMaker('american')
coffeeMakerInstance.coffeeProcess() // 我只吐黑咖啡

ifelse通常改一处会牵扯到整个逻辑,测试时不得不进行回归测试,较为繁琐。想到之前被测试小姐姐追打的场景,我的手指又开始忙碌起来

class CoffeeMaker {
  constructor() {
    // 初始化状态,leftMilk
    this.leftMilk = '100ML';
  }
  american() {
    console.log('牛奶储存量' + this.leftMilk) // 可以轻松获取到实例状态
    console.log('我只吐黑咖啡');
  }
  latte() {
    this.american() // 黑咖啡逻辑复用
    console.log('加点奶');
  }
  vanillaLatte() {
    this.latte() // 拿铁逻辑复用
    console.log('再加香草糖浆');
  }
  mocha() {
    this.latte() // 拿铁逻辑复用
    console.log('再加巧克力');
  }
}

// 逻辑分发
function getCoffee(state) {
  const coffee = new CoffeeMaker();
  if (!coffee[state]) {
    return
  }
  // 对象映射
  return coffee[state]()
}

// 获取咖啡
getCoffee('mocha');
/**
 * 牛奶100ML
  我只吐黑咖啡
  加点奶
  再加巧克力
 */

看着真不错,通过对象映射的方式,将逻辑分离,也可以在处理函数中简单的获取到实例对象的属性。实现状态共享。