状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

使用场景

  1. 有限状态机:当对象有限个状态且在不同状态下具有不同行为时,状态模式是理想的选择。例如,一个订单在“待支付”、“已支付”、“已发货”、“已完成”等状态下有不同的行为和属性。

  2. 对象的行为取决于其状态:如果对象的行为在运行时会随着其内部状态的改变而改变,那么状态模式是一个很好的选择。比如,在游戏中,一个角色的行为可能会因其状态(例如正常、受伤、死亡)而改变。

  3. 避免使用大量的条件语句:状态模式可以避免使用大量的条件语句来检查对象的状态并根据状态执行不同的行为。这样可以使代码更加清晰和易于维护。

  4. 状态间的转换规则复杂:当状态之间的转换规则非常复杂时,使用状态模式可以使得代码更加清晰和易于理解。状态模式将状态转换的逻辑集中在具体的状态类中,使得每个状态的转换规则都变得清晰可见。

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
package main

import "fmt"

// OrderState 定义订单状态接口
type OrderState interface {
handleOrder() // 处理订单
}

// NewOrderState 新建订单状态
type NewOrderState struct{}

func (n *NewOrderState) handleOrder() {
fmt.Println("新建订单已创建")
}

// PaidOrderState 已支付订单状态
type PaidOrderState struct{}

func (p *PaidOrderState) handleOrder() {
fmt.Println("订单已支付")
}

// CompletedOrderState 已完成订单状态
type CompletedOrderState struct{}

func (c *CompletedOrderState) handleOrder() {
fmt.Println("订单已完成")
}

// OrderContext 订单上下文,包含订单状态
type OrderContext struct {
state OrderState
}

// NewOrderContext 创建订单上下文
func NewOrderContext() *OrderContext {
return &OrderContext{state: &NewOrderState{}}
}

// SetState 设置订单状态
func (oc *OrderContext) SetState(state OrderState) {
oc.state = state
}

// ProcessOrder 处理订单
func (oc *OrderContext) ProcessOrder() {
oc.state.handleOrder()
}

func main() {
// 创建新订单上下文
order := NewOrderContext()

// 处理新订单
order.ProcessOrder()

// 支付订单
order.SetState(&PaidOrderState{})
order.ProcessOrder()

// 完成订单
order.SetState(&CompletedOrderState{})
order.ProcessOrder()
}

结语

状态模式能够帮助我们更好地组织对象的行为,并且使得状态的改变更加灵活和可扩展。通过将每种状态的行为封装在具体的状态类中,状态模式使得代码更加清晰、可维护,并且能够避免大量的条件语句。当对象具有有限个状态且在不同状态下具有不同行为时,考虑使用状态模式是一个很好的选择。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。