From a4d2a99dda77e2506f421e43c7ae74f65dd3e582 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Wed, 7 Oct 2020 17:31:55 +0200 Subject: [PATCH] add code example --- behavioral/state/concrete_states.py | 25 ++++++++++++++++++ behavioral/state/context.py | 39 +++++++++++++++++++++++++++++ behavioral/state/main.py | 7 ++++++ behavioral/state/state.py | 28 +++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 behavioral/state/concrete_states.py create mode 100644 behavioral/state/context.py create mode 100644 behavioral/state/main.py create mode 100644 behavioral/state/state.py diff --git a/behavioral/state/concrete_states.py b/behavioral/state/concrete_states.py new file mode 100644 index 0000000..65b66cd --- /dev/null +++ b/behavioral/state/concrete_states.py @@ -0,0 +1,25 @@ +""" +Concrete States implement various behaviors, associated with a state of the +Context. +""" +from behavioral.state.state import State + + +class ConcreteStateA(State): + def handle1(self) -> None: + print("ConcreteStateA handles request1.") + print("ConcreteStateA wants to change the state of the context.") + self.context.transition_to(ConcreteStateB()) + + def handle2(self) -> None: + print("ConcreteStateA handles request2.") + + +class ConcreteStateB(State): + def handle1(self) -> None: + print("ConcreteStateB handles request1.") + + def handle2(self) -> None: + print("ConcreteStateB handles request2.") + print("ConcreteStateB wants to change the state of the context.") + self.context.transition_to(ConcreteStateA()) diff --git a/behavioral/state/context.py b/behavioral/state/context.py new file mode 100644 index 0000000..57aef0b --- /dev/null +++ b/behavioral/state/context.py @@ -0,0 +1,39 @@ +from abc import ABC +from typing import Optional + + +class State(object): + pass + + +class Context(ABC): + """ + The Context defines the interface of interest to clients. It also maintains + a reference to an instance of a State subclass, which represents the current + state of the Context. + """ + + # A reference to the current state of the Context. + _state: Optional[State] = None + + def __init__(self, state: State) -> None: + self.transition_to(state) + + def transition_to(self, state: State) -> None: + """ + The Context allows changing the State object at runtime. + """ + + print(f"Context: Transition to {type(state).__name__ }") + self._state = state + self._state.context = self + + """ + The Context delegates part of its behavior to the current State object. + """ + + def request1(self): + self._state.handle1() + + def request2(self): + self._state.handle2() diff --git a/behavioral/state/main.py b/behavioral/state/main.py new file mode 100644 index 0000000..ea988e5 --- /dev/null +++ b/behavioral/state/main.py @@ -0,0 +1,7 @@ +# The client code. +from behavioral.state.concrete_states import ConcreteStateA +from behavioral.state.context import Context + +context = Context(ConcreteStateA()) +context.request1() +context.request2() diff --git a/behavioral/state/state.py b/behavioral/state/state.py new file mode 100644 index 0000000..9bfc6bb --- /dev/null +++ b/behavioral/state/state.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod + +from behavioral.state.context import Context + + +class State(ABC): + """ + The base State class declares methods that all Concrete State should + implement and also provides a backreference to the Context object, + associated with the State. This backreference can be used by States to + transition the Context to another State. + """ + + @property + def context(self) -> Context: + return self._context + + @context.setter + def context(self, context: Context) -> None: + self._context = context + + @abstractmethod + def handle1(self) -> None: + pass + + @abstractmethod + def handle2(self) -> None: + pass