Python: State Pattern

GeovinDuState.py

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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#状态模式 State  Pattern
class ComputerState(object):
    name = "state"
    allowed = []
 
    def switch(self, state):
        """ Switch to new state """
        if state.name in self.allowed:
            print(
            '当前对象:', self, ' => 切换到新状态', state.name)
            self.__class__ = state
        else:
            print(
            '当前对象:', self, ' => 切换到 ', state.name, '不可能的.')
 
        def __str__(self):
           return self.name
 
# ComputerState
class Off(ComputerState):
 
   name = "off"
   allowed = ['on']
 
# ComputerState
class On(ComputerState):
    """ State of being powered on and working """
    name = "on"
    allowed = ['off', 'suspend', 'hibernate']
 
# ComputerState
class Suspend(ComputerState):
    """ State of being in suspended mode after switched on """
    name = "suspend"
    allowed = ['on']
 
# ComputerState
class Hibernate(ComputerState):
    """ State of being in hibernation after powered on """
    name = "hibernate"
    allowed = ['on']
 
 
class Computer(object):
    """ A class representing a computer """
 
    def __init__(self, model='HP'):
        self.model = model
        # State of the computer - default is off.
        self.state = Off()
 
    def change(self, state):
        """ Change state """
        self.state.switch(state)
 
 
"""2 State class: Base State class"""
 
 
class DuState:
    """Base state. This is to share functionality"""
 
    def scan(self):
        """Scan the dial to the next station"""
        self.pos += 1
 
        """check for the last station"""
        if self.pos == len(self.stations):
            self.pos = 0
        print("参观... 站点是 {} {}".format(self.stations[self.pos], self.name))
 
 
"""Separate Class for AM state of the radio"""
 
 
class AmState(DuState):
    """constructor for AM state class"""
 
    def __init__(self, radio):
        self.radio = radio
        self.stations = ["1250", "1380", "1510"]
        self.pos = 0
        self.name = "AM"
 
    """method for toggling the state"""
 
    def toggle_amfm(self):
        print("切换到 FM")
        self.radio.state = self.radio.fmstate
 
 
"""Separate class for FM state"""
 
 
class FmState(DuState):
    """Constriuctor for FM state"""
 
    def __init__(self, radio):
        self.radio = radio
        self.stations = ["81.3", "89.1", "103.9"]
        self.pos = 0
        self.name = "FM"
 
    """method for toggling the state"""
 
    def toggle_amfm(self):
        print("切换到 AM")
        self.radio.state = self.radio.amstate
 
 
"""Dedicated class Radio"""
 
 
class Radio:
    """A radio. It has a scan button, and an AM / FM toggle switch."""
 
    def __init__(self):
        """We have an AM state and an FM state"""
        self.fmstate = FmState(self)
        self.amstate = AmState(self)
        self.state = self.fmstate
 
    """method to toggle the switch"""
 
    def toggle_amfm(self):
        self.state.toggle_amfm()
 
    """method to scan """
 
    def scan(self):
        self.state.scan()
 
# Geovin Du 3
class Context:
    _state = None
    """ A reference to the current state."""
 
    def __init__(self, state):
        self.transition_to(state)
 
    def transition_to(self, state):
        """Method to make transition"""
 
        print(f"Context: Transition to {type(state).__name__}")
        self._state = state
        self._state.context = self
 
    def request1(self):
        self._state.handle1()
 
    def request2(self):
        self._state.handle2()
 
 
class GeovinState:
    """An abstract class for Concrete sub-classes"""
 
    @property
    def context(self):
        return self._context
 
    @context.setter
    def context(self, context: Context):
        self._context = context
 
    # @abstractmethod
    def handle1(self):
        pass
 
    # @abstractmethod
    def handle2(self):
        pass
 
class State_A(GeovinState):
    def handle1(self):
        print("State_A handles request1.")
        print("State_A wants to change the state of the context.")
        self.context.transition_to(State_B())
 
    def handle2(self):
        print("State_A handles request2.")
 
class State_B(GeovinState):
    def handle1(self):
        print("State_B handles request1.")
 
    def handle2(self):
        print("State_B handles request2.")
        print("State_B wants to change the state of the context.")
        self.context.transition_to(State_A())

  

 

main.py 调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 状态模式 State  Pattern
comp = GeovinDuState.Computer()
comp.change(GeovinDuState.On)
comp.change(GeovinDuState.Off)
comp.change(GeovinDuState.On)
comp.change(GeovinDuState.Suspend)
comp.change(GeovinDuState.Hibernate)
comp.change(GeovinDuState.On)
comp.change(GeovinDuState.Off)
 
radio = GeovinDuState.Radio()
actions = [radio.scan] * 3 + [radio.toggle_amfm] + [radio.scan] * 3
actions *= 2
 
for action in actions:
     action()
 
context = GeovinDuState.Context(GeovinDuState.State_A())
context.request1()
context.request2()

  

输出

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
当前对象: <GeovinDuState.Off object at 0x000001F25CA44CD0=> 切换到新状态 on
当前对象: <GeovinDuState.On object at 0x000001F25CA44CD0=> 切换到新状态 off
当前对象: <GeovinDuState.Off object at 0x000001F25CA44CD0=> 切换到新状态 on
当前对象: <GeovinDuState.On object at 0x000001F25CA44CD0=> 切换到新状态 suspend
当前对象: <GeovinDuState.Suspend object at 0x000001F25CA44CD0=> 切换到  hibernate 不可能的.
当前对象: <GeovinDuState.Suspend object at 0x000001F25CA44CD0=> 切换到新状态 on
当前对象: <GeovinDuState.On object at 0x000001F25CA44CD0=> 切换到新状态 off
参观... 站点是 89.1 FM
参观... 站点是 103.9 FM
参观... 站点是 81.3 FM
切换到 AM
参观... 站点是 1380 AM
参观... 站点是 1510 AM
参观... 站点是 1250 AM
参观... 站点是 1380 AM
参观... 站点是 1510 AM
参观... 站点是 1250 AM
切换到 FM
参观... 站点是 89.1 FM
参观... 站点是 103.9 FM
参观... 站点是 81.3 FM
Context: Transition to State_A
State_A handles request1.
State_A wants to change the state of the context.
Context: Transition to State_B
State_B handles request2.
State_B wants to change the state of the context.
Context: Transition to State_A

  

 

posted @   ®Geovin Du Dream Park™  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示