Skip to main content
deleted 13 characters in body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

Surely this is a common problem and has already been solved? What is the standard design to use in a situation like this? If there isn't a standard design pattern, Dodo you think the design I have suggested is good design?

Thanks.

Surely this is a common problem and has already been solved? What is the standard design to use in a situation like this? If there isn't a standard design pattern, Do you think the design I have suggested is good design?

Thanks.

Surely this is a common problem and has already been solved? What is the standard design to use in a situation like this? If there isn't a standard design pattern, do you think the design I have suggested is good design?

Rollback to Revision 5
Source Link
Mast
  • 13.9k
  • 12
  • 57
  • 128

In the real system, the predicates are not as simple as this. An example from my requirements is:

a implies b && (c ∥ d) && e where each letter is a particular state of a piece of equipment. The states are also more complex, for example, one state might be item1 is inside item2 exclusion zone. There are also transition states, such as "Turning On", and "Turning Off".

#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [Item1_OnState[item1_OnState ]             [Item2_OnState][item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = Item1_OnStateitem1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = Item2_OnStateitem2_OnState(self._fsm)

class Item1_OnStateitem1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class Item2_OnStateitem2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> Item1_OnStateitem1_OnState
    # <turning off 1>
    # system : Item1_OnStateitem1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> Item2_OnStateitem2_OnState

In the real system, the predicates are not as simple as this. An example from my requirements is:

a implies b && (c ∥ d) && e where each letter is a particular state of a piece of equipment. The states are also more complex, for example, one state might be item1 is inside item2 exclusion zone. There are also transition states, such as "Turning On", and "Turning Off".

#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [Item1_OnState ]             [Item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = Item1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = Item2_OnState(self._fsm)

class Item1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class Item2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> Item1_OnState
    # <turning off 1>
    # system : Item1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> Item2_OnState
#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [item1_OnState ]             [item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = item1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = item2_OnState(self._fsm)

class item1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class item2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> item1_OnState
    # <turning off 1>
    # system : item1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> item2_OnState
added 42 characters in body
Source Link
Blue7
  • 373
  • 2
  • 10

In the real system, the predicates are not as simple as this. An example from my requirements is:

a implies b && (c ∥ d) && e where each letter is a particular state of a piece of equipment. The states are also more complex, for example, one state might be item1 is inside item2 exclusion zone. There are also transition states, such as "Turning On", and "Turning Off".

#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [item1_OnState[Item1_OnState ]             [item2_OnState][Item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = item1_OnStateItem1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = item2_OnStateItem2_OnState(self._fsm)

class item1_OnStateItem1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class item2_OnStateItem2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> item1_OnStateItem1_OnState
    # <turning off 1>
    # system : item1_OnStateItem1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> item2_OnStateItem2_OnState
#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [item1_OnState ]             [item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = item1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = item2_OnState(self._fsm)

class item1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class item2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> item1_OnState
    # <turning off 1>
    # system : item1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> item2_OnState

In the real system, the predicates are not as simple as this. An example from my requirements is:

a implies b && (c ∥ d) && e where each letter is a particular state of a piece of equipment. The states are also more complex, for example, one state might be item1 is inside item2 exclusion zone. There are also transition states, such as "Turning On", and "Turning Off".

#                     ,----------------------------,
#                     v                            |
#    ,----------[BothOffState]--------,            |
#    | turnOn1()                      | turnOn2()  |
#    v                                v            |
# [Item1_OnState ]             [Item2_OnState]     |
#        | turnOff1()                | turnOff2()  |
#        `---------------------------'-------------'
#
class IState(metaclass=ABCMeta):
     def __init__(self, fsm):
        print("system : " + fsm.currentState.__class__.__name__ + " -> " + self.__class__.__name__)
        self._fsm = fsm

class BothOffState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOn1(self):
        self._fsm.currentState = Item1_OnState(self._fsm)
        
    def turnOn2(self):
        self._fsm.currentState = Item2_OnState(self._fsm)

class Item1_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff1(self):
        self._fsm.currentState = BothOffState(self._fsm)

class Item2_OnState(IState):
    def __init__(self, fsm):
        super().__init__(fsm)
        
    def turnOff2(self):
        self._fsm.currentState = BothOffState(self._fsm)

class FSM:
    currentState = None
    def __init__(self):
        self.currentState = BothOffState(self)
if __name__ == "__main__":
    
    system = FSM()
    print("<turning on 1>")
    system.currentState.turnOn1()
    #system.currentState.turnOn2() AttributeError because this state transition doesn't exist
    print("<turning off 1>")
    system.currentState.turnOff1()
    print("<turning on 2>")
    system.currentState.turnOn2()
    
    #Output:
    #
    # system : NoneType -> BothOffState
    # <turning on 1>
    # system : BothOffState -> Item1_OnState
    # <turning off 1>
    # system : Item1_OnState -> BothOffState
    # <turning on 2>
    # system : BothOffState -> Item2_OnState
added 42 characters in body
Source Link
Blue7
  • 373
  • 2
  • 10
Loading
edited title
Link
BCdotWEB
  • 11.4k
  • 2
  • 28
  • 45
Loading
Tweeted twitter.com/StackCodeReview/status/1252839579729588224
spelling
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257
Loading
added 76 characters in body
Source Link
Blue7
  • 373
  • 2
  • 10
Loading
Source Link
Blue7
  • 373
  • 2
  • 10
Loading