• Python: State Pattern


    GeovinDuState.py

    #状态模式 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 调用:

    # 状态模式 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()
    

      

    输出

    当前对象: <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
    

      

  • 相关阅读:
    Spring基础知识点总结
    秒懂设计模式--代理模式(proxy)
    秒懂设计模式--工厂模式
    秒懂设计模式--适配器模式
    秒懂设计模式--装饰者模式
    秒懂设计模式--观察者模式
    单例模式的几种实现
    springboot2.0+spring cloud+eureka搭建微服务步骤
    字符串排序算法
    bitbucket的简单使用
  • 原文地址:https://www.cnblogs.com/geovindu/p/16830610.html
Copyright © 2020-2023  润新知