⑩状态模式

避免陷入在 if/else 之中

考虑以下两种场景,哪种更容易让你深陷在 if/else 的逻辑之中。

订单配送,订单可能处于下面的几种状态

  • 下单状态
  • 打包状态
  • 配送状态
  • 签收状态

自动售卖机

  • 无货状态
  • 有货状态
  • 已投币状态
  • 未投币状态
  • 出货状态

显然订单配送的状态处理起来更容易一些

  • 下单状态需要备货
  • 打包状态需要检查时候安全,是否要放入小礼物
  • 配送状态要同步配送信息
  • 签收状态要回访客户

虽然这些状态环环相扣,但是一旦状态完成转移就不需要在考虑原有状态中的行为是否还需要关注。

而自动售售货机可能让你陷入 if/else 的深渊,因为不同的状态可能伴随相同的操作,无论处于哪种状态,用户都可能按下取货按钮,但只有投币并且有货,按下取货才有意义。

状态模式

状态模式:允许对象在内部状态改变的时候改变他的行为,对象看起来好像修改了它的类。

状态模式和策略模式中的组合对象很像,但是状态模式更专注与状态的迁移,和不同状态中的行为。

  • 状态模式允许一个对象基于内部状态而拥有不同的行为。
  • 和程序状态机(PSM)不同,状态模式用类代表状态
  • Context 会将行为委托给当前对象
  • 通过将每个状态封装进一个类,我们把以后需要做的任何变化都局部化了
  • 状态模式允许 Context 随着状态改变而改变行为
  • 状态转移可以由 State 类或 Context 类控制
  • 使用状态模式通常会导致设计中类的数目大量增加
  • 状态类可以被多个 Context 实例共享
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// 投币
// 点击出货

abstract class State {
machine: VendingMachine;
constructor(machine: VendingMachine) {
this.machine = machine;
}
addCoin(coin?: Number) {
console.log("必须实现 addCoin");
}
getProduct() {
console.log("必须实现 getProduct");
}
}

// 无商品

class NoProduct extends State {
addCoin() {
console.log("机器里无商品,你不能购买");
}
getProduct() {
console.log("机器里无商品,你不能购买");
}
}

class HasProduct extends State {
addCoin(coin: number) {
this.machine.coin += coin;
}
getProduct() {
console.log("你已经获取了商品");
this.machine.count -= 1;
this.machine.coin -= 1;
this.stateTransform();
}
stateTransform() {
const { count, coin } = this.machine;
if (coin === 0) {
this.machine.setState(this.machine.stateNoCoin);
} else if (count === 0) {
this.machine.setState(this.machine.stateNoProduct);
}
}
}

class NoCoin extends State {}

class VendingMachine {
stateNoProduct: NoProduct;
stateHasProduct: HasProduct;
stateNoCoin: NoCoin;
count: number;
coin: number = 0;
state: NoProduct | HasProduct;
constructor(count: number) {
this.count = count || 2;
this.stateNoProduct = new NoProduct(this);
this.stateHasProduct = new HasProduct(this);
this.stateNoCoin = new NoCoin(this);
this.state = this.stateHasProduct;
}
setState(state: NoProduct | HasProduct) {
this.state = state;
}
addCoin(coin = 0) {
this.state.addCoin(coin);
}
getProduct() {
this.state.getProduct();
}
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2025 SunZhiqi

此时无声胜有声!

支付宝
微信