状态模式 和 策略模式 分不清?可以问问 chatgpt塞

本文正在参加「金石计划」

本文主要内容:

  1. 状态模式
  2. 状态模式 与 策略模式 的区别

本文属于我的前端需要掌握的设计模式专栏。上一篇# 很多人早都已经实践策略模式了,却说不知道策略模式是啥?

状态模式是啥

定义

有状态的模式?我们先看看百度百科对其定义:

允许一个对象在其内部状🤛🏻态改变时改变它的行为。

还真是和状态有关系。看完有点似懂非懂的样子,那要不问一下 chatgpt ?chatgpt 的回答是这样的:

状态模式 和 策略模式 分不清?可以问问 chatgpt塞

😌说得还挺详细哈!感觉快懂了,让他举个例子加深一下理解:

状态模式 和 策略模式 分不清?可以问问 chatgpt塞

好的,我差不多明白了,谢谢您嘞!

🌰

相信掘友们看完 chatgpt 的回答,都大概知道了 状态模式 是个啥,接下来就以 chatgpt 给的例子模拟一台自动售货机。

假设我们的机器只卖一种商品 && 假设找的零钱都是 1 元硬币。

const { log } = console

class AutoSellMachine {
  constructor() {
    // 状态:
    // 无货: out-of-stock
    // 正常: normal
    // 有货无法找零:unable-to-change
    this.state = 'normal' // 初始化是正常状态
    this.count = 100 // 商品数量
    this.price = 5 // 单价
    this.realMoney = 0 // 找零后的钱
    this.money = 100 // 机器里用来找零的钱
  }
  getState(byCount, money) {
    if (this.count < byCount) {
      return 'out-of-stock'
    } else if (this.count >= byCount && this.money < money - byCount * this.price) {
      return 'unable-to-change'
    } else {
      return normal
    }
  }
  onBusiness(byCount, money) {
    this.state = this.getState()
    if (this.state = 'out-of-stock') {
      log('抱歉!没货啦')
    } else if (this.state = 'unable-to-change') {
      log('抱歉!找不了零钱啦')
    } else {
      const temp = byCount * this.price
      this.realMoney += temp
      this.money -= temp
      this.count -= byCount
      this.state = this.count === 0 ? 'out-of-stock' : 'normal' // 卖掉这次之后的状态
      log('购买成功啦')
    }
  }
}

哎,不对呀,这个 if/else 怎么越看越不顺眼呢?学过策略模式的你见到这个代码可能手痒痒了,一顿操作后:

const { log } = console

class AutoSellMachine {
  constructor() {
    // 状态:
    // 无货: out-of-stock
    // 正常: normal
    // 有货无法找零:unable-to-change
    this.state = 'normal' // 初始化是正常状态
    this.count = 100 // 商品数量
    this.price = 5 // 单价
    this.realMoney = 0 // 找零后的钱
    this.money = 100 // 机器里用来找零的钱
  }
  getState(byCount, money) {
    if (this.count < byCount) {
      return 'out-of-stock'
    } else if (this.count >= byCount && this.money < money - byCount * this.price) {
      return 'unable-to-change'
    } else {
      return normal
    }
  }
  onBusiness(byCount, money) {
    this.state = this.getState(byCount, money)
    diffProcess[this.state](byCount)
  }
}

const diffProcess = {
  normal(byCount) {
    const temp = byCount * this.price
    this.realMoney += temp
    this.money -= temp
    this.count -= byCount
    this.state = this.count === 0 ? 'out-of-stock' : 'normal' // 卖掉这次之后的状态
  },
  'out-of-stock'() {
    log('抱歉!没货啦')
  },
  'unable-to-change'() {
    log('抱歉!找不了零钱啦')
  }
}

完了你发现,这不就是策略模式么?所以这两种模式的区别到底在哪里?于是又开始去问 chatgpt:

状态模式 和 策略模式 分不清?可以问问 chatgpt塞

看完过后还是不太清楚?仔细看看最后的代码,你就能找到一点端倪。

const diffProcess = {
  normal(byCount) {
    const temp = byCount * this.price
    this.realMoney += temp
    this.money -= temp
    this.count -= byCount
    this.state = this.count === 0 ? 'out-of-stock' : 'normal' // 卖掉这次之后的状态
  },
}

上面这段逻辑实际运行是会报错的,里面的 this 是有问题的,此处的 this 指向 diffProcess,但我们期望它指向 AutoSellMachine 实例,因为逻辑中的运算需要实例的状态。

我们应该这么来:

const { log } = console

class AutoSellMachine {
  constructor() {
    // 状态:
    // 无货: out-of-stock
    // 正常: normal
    // 有货无法找零:unable-to-change
    this.state = 'normal' // 初始化是正常状态
    this.count = 100 // 商品数量
    this.price = 5 // 单价
    this.realMoney = 0 // 找零后的钱
    this.money = 100 // 机器里用来找零的钱
  }
  diffProcess = {
    instance: this,
    normal(byCount) {
      const temp = byCount * instance.price
      instance.realMoney += temp
      instance.money -= temp
      instance.count -= byCount
      instance.state = instance.count === 0 ? 'out-of-stock' : 'normal' // 卖掉这次之后的状态
    },
    'out-of-stock'() {
      log('抱歉!没货啦')
    },
    'unable-to-change'() {
      log('抱歉!找不了零钱啦')
    }
  }

  getState(byCount, money) {
    if (this.count < byCount) {
      return 'out-of-stock'
    } else if (this.count >= byCount && this.money < money - byCount * this.price) {
      return 'unable-to-change'
    } else {
      return normal
    }
  }
  onBusiness(byCount, money) {
    this.state = this.getState(byCount, money)
    this.diffProcess[this.state](byCount)
  }
}

是不是瞬间恍然大悟,那来总结一下:

  • 共同点
    • 状态模式、策略模式封装行为、都通过委托来实现行为分发。
  • 不同点
    • 状态模式封装的行为会依赖类实例的状态,也就是和实例存在一定的关联;策略模式则没有关联。

总结

本文主要通过一个例子讲了下面两点内容:

  1. 状态模式
  2. 状态模式 与 策略模式 的区别

若有说得不对的,欢迎评论区指正噢😃

原文链接:https://juejin.cn/post/7215963267491184700 作者:Lvzl

(0)
上一篇 2023年3月30日 下午4:10
下一篇 2023年3月30日 下午4:21

相关推荐

发表回复

登录后才能评论