Skip to content

Commit 93b946c

Browse files
committed
State: add structural example
1 parent f8ae248 commit 93b946c

2 files changed

Lines changed: 139 additions & 0 deletions

File tree

src/State/Structure/Output.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Context: Transition to ConcreteStateA
2+
ConcreteStateA handles request1.
3+
ConcreteStateA wants to change the state of the context.
4+
Context: Transition to ConcreteStateB
5+
ConcreteStateB handles request2.
6+
ConcreteStateB wants to change the state of the context.
7+
Context: Transition to ConcreteStateA

src/State/Structure/main.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""
2+
EN: State Design Pattern
3+
4+
Intent: Allow an object to alter its behavior when its internal state
5+
changes. The object will appear to change its class.
6+
7+
RU: Паттерн Состояние
8+
9+
Назначение: Позволяет объекту менять поведение при изменении его внутреннего
10+
состояния. Со стороны может казаться, что объект меняет свой класс.
11+
"""
12+
13+
14+
from __future__ import annotations
15+
from abc import ABCMeta, abstractmethod
16+
17+
18+
class Context(metaclass=ABCMeta):
19+
"""
20+
EN: The Context defines the interface of interest to clients. It also
21+
maintains a reference to an instance of a State subclass, which represents
22+
the current state of the Context.
23+
24+
RU: Контекст определяет интерфейс, представляющий интерес для клиентов. Он
25+
также хранит ссылку на экземпляр подкласса Состояния, который отображает
26+
текущее состояние Контекста.
27+
"""
28+
29+
_state = None
30+
"""
31+
EN: A reference to the current state of the Context.
32+
33+
RU: Ссылка на текущее состояние Контекста.
34+
"""
35+
36+
def __init__(self, state: State):
37+
self.transition_to(state)
38+
39+
def transition_to(self, state: State):
40+
"""
41+
EN: The Context allows changing the State object at runtime.
42+
43+
RU: Контекст позволяет изменять объект Состояния во время выполнения.
44+
"""
45+
46+
print(f"Context: Transition to {type(state).__name__}")
47+
self._state = state
48+
self._state.context = self
49+
50+
"""
51+
EN: The Context delegates part of its behavior to the current State
52+
object.
53+
54+
RU: Контекст делегирует часть своего поведения текущему объекту
55+
Состояния.
56+
"""
57+
58+
def request1(self):
59+
self._state.handle1()
60+
61+
def request2(self):
62+
self._state.handle2()
63+
64+
65+
class State(metaclass=ABCMeta):
66+
"""
67+
EN: The base State class declares methods that all Concrete State should
68+
implement and also provides a backreference to the Context object, associated
69+
with the State. This backreference can be used by States to transition the
70+
Context to another State.
71+
72+
RU: Базовый класс Состояния объявляет методы, которые должны реализовать все
73+
Конкретные Состояния, а также предоставляет обратную ссылку на объект
74+
Контекст, связанный с Состоянием. Эта обратная ссылка может использоваться
75+
Состояниями для передачи Контекста другому Состоянию.
76+
"""
77+
78+
@property
79+
def context(self) -> Context:
80+
return self._context
81+
82+
@context.setter
83+
def context(self, context: Context) -> None:
84+
self._context = context
85+
86+
@abstractmethod
87+
def handle1(self) -> None:
88+
pass
89+
90+
@abstractmethod
91+
def handle2(self) -> None:
92+
pass
93+
94+
95+
"""
96+
EN: Concrete States implement various behaviors, associated with a state of
97+
the Context.
98+
99+
RU: Конкретные Состояния реализуют различные модели поведения, связанные с
100+
состоянием Контекста.
101+
"""
102+
103+
104+
class ConcreteStateA(State):
105+
def handle1(self) -> None:
106+
print("ConcreteStateA handles request1.")
107+
print("ConcreteStateA wants to change the state of the context.")
108+
self.context.transition_to(ConcreteStateB())
109+
110+
def handle2(self) -> None:
111+
print("ConcreteStateA handles request2.")
112+
113+
114+
class ConcreteStateB(State):
115+
def handle1(self) -> None:
116+
print("ConcreteStateB handles request1.")
117+
118+
def handle2(self) -> None:
119+
print("ConcreteStateB handles request2.")
120+
print("ConcreteStateB wants to change the state of the context.")
121+
self.context.transition_to(ConcreteStateA())
122+
123+
124+
if __name__ == "__main__":
125+
"""
126+
EN: The client code.
127+
128+
RU: Клиентский код.
129+
"""
130+
context = Context(ConcreteStateA())
131+
context.request1()
132+
context.request2()

0 commit comments

Comments
 (0)