状态模式
状态模式,当对象的内部状态发生了改变的时候,允许对象执行不同的流程。
优点:
- 封装了状态转换规则。
- 枚举了可能的状态,在枚举状态之前需要确定状态的种类。
- 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
- 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
- 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点:
- 状态模式的使用必然会增加系统类和对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
- 状态模式对 “开闭原则” 并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。
应用场景
- 行为随状态改变而改变的场景。
- 条件、分支语句的代替者。
代码示例
这是一个状态图,具有 “有 25 分钱”、“没有 25 分钱”、“售出糖果”、“糖果售罄” 这 4 个状态。同时也对应 4 个动作:“投入 25 分钱”,“退回 25 分钱”,“转动曲柄” 和 “发放糖果”。
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
class State: # 定义state基类 def insert_quarter( self ): pass def eject_quarter( self ): pass def turn_crank( self ): pass def dispense( self ): pass class SoldOutState(State): # 继承State 类 def __init__( self , gumball_machine): self .gumball_machine = gumball_machine def __str__( self ): return "sold_out" def insert_quarter( self ): print ( "You can't insert a quarter, the machine is sold out" ) def eject_quarter( self ): print ( "You can't eject, you haven't inserted a quarter yet" ) def turn_crank( self ): print ( "You turned, but ther are no gumballs" ) def dispense( self ): print ( "No gumball dispensed" ) class SoldState(State): # 继承State 类 def __init__( self , gumball_machine): self .gumball_machine = gumball_machine def __str__( self ): return "sold" def insert_quarter( self ): print ( "Please wait, we're already giving you a gumball" ) def eject_quarter( self ): print ( "Sorry, you already turned the crank" ) def turn_crank( self ): print ( "Turning twice doesn't get you another gumball" ) def dispense( self ): self .gumball_machine.release_ball() if gumball_machine.count > 0 : self .gumball_machine.state = self .gumball_machine.no_quarter_state else : print ( "Oops, out of gumballs!" ) self .gumball_machine.state = self .gumball_machine.soldout_state class NoQuarterState(State): # 继承State 类 def __init__( self , gumball_machine): self .gumball_machine = gumball_machine def __str__( self ): return "no_quarter" def insert_quarter( self ): # 投币 并且改变状态 print ( "You inserted a quarter" ) self .gumball_machine.state = self .gumball_machine.has_quarter_state def eject_quarter( self ): print ( "You haven't insert a quarter" ) def turn_crank( self ): print ( "You turned, but there's no quarter" ) def dispense( self ): print ( "You need to pay first" ) class HasQuarterState(State): # 继承State 类 def __init__( self , gumball_machine): self .gumball_machine = gumball_machine def __str__( self ): return "has_quarter" def insert_quarter( self ): print ( "You can't insert another quarter" ) def eject_quarter( self ): print ( "Quarter returned" ) self .gumball_machine.state = self .gumball_machine.no_quarter_state def turn_crank( self ): print ( "You turned..." ) self .gumball_machine.state = self .gumball_machine.sold_state def dispense( self ): print ( "No gumball dispensed" ) class GumballMachine: def __init__( self , count = 0 ): self .count = count # 找出所有状态,并创建实例变量来持有当前状态,然后定义状态的值 self .soldout_state = SoldOutState( self ) self .no_quarter_state = NoQuarterState( self ) self .has_quarter_state = HasQuarterState( self ) self .sold_state = SoldState( self ) if count > 0 : self .state = self .no_quarter_state else : self .state = self .soldout_state def __str__( self ): return ">>> Gumball machine current state: %s" % self .state def insert_quarter( self ): # 投入25分钱 self .state.insert_quarter() def eject_quarter( self ): # 退回25分 self .state.eject_quarter() # print("state", self.state, type(self.state)) def turn_crank( self ): # 转动曲柄 # print("state", self.state, type(self.state)) self .state.turn_crank() def release_ball( self ): # 发放糖果 print ( "A gumball comes rolling out the slot..." ) if self .count > 0 : self .count - = 1 if __name__ = = "__main__" : # 以下是代码测试 gumball_machine = GumballMachine( 5 ) # 装入5 个糖果 print (gumball_machine) gumball_machine.insert_quarter() # 投入25分钱 gumball_machine.turn_crank() # 转动曲柄 print (gumball_machine) gumball_machine.insert_quarter() #投入25分钱 gumball_machine.eject_quarter() # 退钱 gumball_machine.turn_crank() # 转动曲柄 print (gumball_machine) gumball_machine.insert_quarter() # 投入25分钱 gumball_machine.turn_crank() # 转动曲柄 gumball_machine.insert_quarter() # 投入25分钱 gumball_machine.turn_crank() # 转动曲柄 gumball_machine.eject_quarter() # 退钱 print (gumball_machine) |
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/Jmilk/article/details/122933989