Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who defines state transitions in the state pattern?

I understand that the State pattern can be used to model objects that changes behavior depending on the state and the various states that the Context can have is encapsulated in concrete classes that represent a State interface . What I am not clear is how the state transitions happen in this pattern . Do the individual states know and decide who follows them or is it the Context that decides which state it will get next ?

like image 241
Geek Avatar asked Jan 21 '13 07:01

Geek


2 Answers

From the GOF Design Patterns book (This is there in the Implementation section):

1. Who defines the state transitions? The State pattern does not specify which participant defines the criteria for state transitions. If the criteria are fixed,then they can be implemented entirely in the Context. It is generally more flexible and appropriate, however, to let the State subclasses themselves specify their successor state and when to make the transition. This requires adding an interface to the Context that lets State objects set the Context's current state explicitly.

Decentralizing the transition logic in this way makes it easy to modify or extend the logic by defining new State subclasses. A disadvantage of decentralization is that one State subclass will have knowledge of at least one other, which introduces implementation dependencies between subclasses.

like image 54
user1168577 Avatar answered Sep 21 '22 23:09

user1168577


May be a relatively concrete example can clarify. I hope I am understanding it correctly

Suppose a washing machine has two states (ON, Off). Following GoF vocabulary:

  • Context => WashingMachine
  • State => WashingMachineState
  • Concrete states => StateOn, StateOff

For state transition, via state subclasses (in our case StateOn and StateOff) we need to have a method to change state Context:

class WashingMachine {
   WashingMachineState state;
   ...
   protected void setState(WashingMachineState newState) {
      state = newState;
   }

   someMethod () {
      ...
      state.pushStartButton(this);
      ...
   }
}
abstract class WashingMachineState {
   protected void run();
   protected void pushStartButton(WashingMachine wm);
}
class StateOn extends WashingMachineState {
   ...
   void pushStartButton(WashingMachine wm) {
      wm.setState(new StateOff())
   }
}

class StateOff extends WashingMachineState {
   ...
   void pushStartButton(WashingMachine wm) {
      wm.setState(new StateOn())
   }
}

Just keep in mind there are several ways to implement it, creativity helps!

like image 34
ShazSimple Avatar answered Sep 25 '22 23:09

ShazSimple