Talk:State pattern

message: I don't think the sample here is of the state pattern neither.  My understanding is that each of the state in the context space should be represented by a concrete class of the type with its implementation of the action(s) including state change.  And the object keeps the current state value throughout the procedure.
:I have added a client to the code, which I hope will clear up the confusion. This drawing tools example is very similar to that in the diagram on p. 313 of the GoF book. Babomb 06:25, 18 March 2006 (UTC)
replies: text:  The example is still wrong, as is the whole article.  The crucial difference between the state design pattern and the strategy design pattern is that the state pattern is a strategy pattern that is responsible for switching to different states, thus actually implementing a state machine.  If the example doesn't showcase any transition between states handled by each concrete implementation of the state interface then clearly it doesn't represent a state machine.  A state machie, to be an actual state machine, needs to showcase transitions between states, and the examples don't. -- Mecanismo | Talk 15:12, 15 May 2016 (UTC)
thread_title:  my understanding 

message: I agree your example is not a state pattern, because the "states" (your tools) do not model the transitions. When I use this pattern, not only the operations but also the state transitions are delegated to the states themselves. Here, your DrawingController controls the whole transition table hence you gain almost no expressiveness over a switch statement.
To me, your example is quite as good an example as one for the Strategy pattern.
I don't quite remember the example the GoF use but here is one involving a two-state printer (in Java):
 package printer;
 
 public class Printer {
    private PrinterState state;
    public Printer () {
       state = new OnLineState(); // default state is on-line
    }
    public void print (Document doc) {
       state = state.print(doc);
    }
 }
 
 interface PrinterState {
    PrinterState print (Document doc);
 }
 
 class OnLineState implements PrinterState {
    public PrinterState print (Document doc) {
       PrintState nextState = this;
       try {
          doc.print();
       }
       catch (OffLineException x) { // maybe no more paper?
          nextState = new OffLineState();
       }
       return nextState;
    }
 }
 
 class OffLineState implements PrinterState {
    public PrinterState print (Document doc) {
       waitOnlineButton();
       return new OnLineState().print(doc);
    }
    private void waitOnlineButton () {
       // implementation not relevant
    }
 }
Hope it helps (you may use this code as you see fit, or even delete it if you find it irrelevant)
--Cadrian 14:40, 20 April 2006 (UTC)
thread_title:  a printer 

message: Hi All,
I am going through different patterns currently. I had tried to implement the State pattern with this example. Please comment whether this example is correct or not. BTW, I have taken it from GOF's book.
//Example of State Pattern
#include <iostream.h>
class Context;
class State;
class FirstState;
class SecondState;
class ThirdState;
class State
{
public:
	//State(Context* t):m_t(t){}
	virtual void FirstFunction(Context* t){}//has been implemented in the first state
	virtual void SecondFunction(Context* t){}//has been implemented in the second state
	virtual void ThirdFunction(Context* t){}//has been implemented in the thirs state
protected:
	void StateChange(Context* t, State* s);//{t->StateChange(s);}//has been implemented later
private:
	//Context* m_t;
};
class FirstState : public State
{
public:
	
	FirstState(){}
	void FirstFunction(Context* t);
	/*
	{
		cout<<"Inside first state. It will turn on second state."<<endl;
		StateChange(t, SecondState::Instance());
	}
	*/
	static State* Instance()
	{
		return new FirstState();
		/*
		if(FirstStateInstance == 0)
			FirstStateInstance =  new FirstState();
		return FirstStateInstance;
		*/
	}
private:
	static State* FirstStateInstance;
	
};
class SecondState : public State
{
public:
	SecondState(){}
	void  SecondFunction(Context* t);
	/*	
	{
		cout<<"Inside second state. It will turn on third state."<<endl;
		t->ChangeState(ThirdState::Instance());
	}
	*/
	
	static State* Instance()
	{
		return new SecondState();
		/*
		if(instance == 0)
			instance =  new SecondState();
		return instance;
		*/
	}
private:
	static State* instance;
};
class ThirdState : public State
{
public:
	ThirdState(){}
	void ThirdFunction(Context* t)
	{
		cout<<"Inside third cum last state."<<endl;
	}
	static State* Instance()
	{
		/*
		if(instance == 0)
			instance =  new ThirdState();
		return instance;
		*/
		return new ThirdState();
	}
private:
	static State* instance;
};
//enum PresentState{State1 = FirstState::Instance(), State2 = SecondState::Instance(), State3 = ThirdState::Instance()};
class Context
{
public:
	Context() {stateObj = FirstState::Instance();}
	void FirstFunction()
	{
		stateObj->FirstFunction(this);
		SecondFunction();
	}
	void SecondFunction()
	{
		
		stateObj->SecondFunction(this);
		ThirdFunction();
	}
	
	void ThirdFunction()
	{
		stateObj->ThirdFunction(this);
	}
	void StateChange(State* s){stateObj = s;}
	
private:
	State* stateObj;
};
void State::StateChange(Context* t, State* s){t->StateChange(s);}
void FirstState::FirstFunction(Context* t)
{
	cout<<"Inside first state. It will turn on second state."<<endl;
	StateChange(t, SecondState::Instance());
}
void  SecondState::SecondFunction(Context* t)
{
	cout<<"Inside second state. It will turn on third state."<<endl;
	t->StateChange(ThirdState::Instance());
}
void main()
{
	Context* context = new Context();
	context->FirstFunction();
}
: That looks about right. Do note that you leak memory, though. Obviously you leak the Context you new in main() (which doesn't really matter here but is sloppy), but you also haven't defined a destructor for Context so it's not clear who should be deleting the State a Context has a pointer to. Since the State objects appear to be singletons, I'd guess you don't plan to delete them, but if they are singletons, they should have a private destructor so you don't accidentally make other instances of them. Also, you'll need to initialize the instance pointers to NULL or else checking for nullness won't do what you want. —Ben FrantzDale 11:32, 19 June 2006 (UTC)
thread_title:  please comment 

message: This is definitely not a State pattern realization. States represent internal state of a system that alters/transitions over interactions, thereby altering behaviour. The crucial point here is that States must be transitory and the transitions must be internal to the object whose state is being abstracted.
The exapmle presented is clearly a realization of a Strategy pattern where the DrawingController abstracts mouse interaction into a generic Tool with two Tool implementations that exhibit different interaction behaviours. Neither Tool transitions into the other, nor is the Tool interface capable of transitions.
The State pattern is actually a modelling of UML State charts. Hence the necessity of internal event-based transitions.
PS- The Tool analogy was more aptly used in GoF as a realization of the Prototype pattern.
--203.197.90.149 07:48, 23 June 2006 (UTC)
thread_title:  Internal State vs Behavioural Strategy 

message: Please comment on this Sample Example
Dear All,
Here is my version of the state Pattern. Please comment on this. Previously I submitted another sample, but this one is implemented differently. I also wanted to upload the class diagrams and the sequence diagram of this sample. But I am not sure how to do that. 
#include <iostream.h>
class Context;
class State;
class FirstState;
class SecondState;
class ThirdState;
class State
{
public:
	virtual void FirstFunction(Context* t){}//this will implement the function of the first state
	virtual void SecondFunction(Context* t){}//this will implement the function of the second state
	virtual void ThirdFunction(Context* t){}//this will implement the function of the third state
};
class FirstState : public State
{
public:
	
	FirstState(){}
	void FirstFunction(Context* t);//Implementation later in the file
	
	static State* Instance()
	{
		if(FirstStateInstance == NULL)
			FirstStateInstance =  new FirstState();
		return FirstStateInstance;
		
	}
private:
	static State* FirstStateInstance;
	~FirstState(){};
	
};
State* FirstState::FirstStateInstance = NULL;
class SecondState : public State
{
public:
	SecondState(){}
	void  SecondFunction(Context* t);//Implementation later in the file
		
	static State* Instance()
	
        {
		if(SecondStateInstance == NULL)
			SecondStateInstance =  new SecondState();
		return SecondStateInstance;
		
	}
private:
	static State* SecondStateInstance;
	~SecondState(){}
};
State* SecondState::SecondStateInstance = NULL;
class ThirdState : public State
{
public:
	ThirdState(){}
	void ThirdFunction(Context* t)
	
        {
		cout<<"Inside third cum last state."<<endl;
	}
	static State* Instance()
	{
		
		if(ThirdStateInstance == 0)
			ThirdStateInstance =  new ThirdState();
		return ThirdStateInstance;
		}
private:
	static State* ThirdStateInstance;
	~ThirdState(){}
};
State* ThirdState::ThirdStateInstance = NULL;
class Context
{
public:
	enum EState{EFirstState,ESecondState,EThirdState};
	Context()
 
	{
		stateObj = FirstState::Instance();
		PresentState = EFirstState;
	
       }
	void Run()
	{
		switch(PresentState)
		{
		case EFirstState:
			stateObj->FirstFunction(this);
			break;
		case ESecondState:
			stateObj->SecondFunction(this);
			break;
		case EThirdState:
			stateObj->ThirdFunction(this);
                        break;
		
                }
	}
	void StateChange(State* s, EState state)
	{
		stateObj = s;
		PresentState = state;
	
       }
	~Context()
	
         {
		delete stateObj;
		stateObj = NULL;
	
          }
	
private:
	State* stateObj;
	int PresentState;
};
void FirstState::FirstFunction(Context* t)
{
	cout<<"Inside first state. It will turn on second state."<<endl;
	t->StateChange(SecondState::Instance(), t->ESecondState);
	t->Run();
}
void  SecondState::SecondFunction(Context* t)
{
	cout<<"Inside second state. It will turn on third state."<<endl;
	t->StateChange(ThirdState::Instance(), t->EThirdState);
	t->Run();
}
void main()
{
	Context* context = new Context();
	context->Run();
	delete context;
}
--Som mukhopadhyay 11:32, 17 July 2006 (UTC)
thread_title:  '''How about this implementation'''

message: In the hope this helps the discussion a bit, this is the code copied from the book (Design Patterns : elements of reusable object-oriented software / Erich Gamma [et al.]  pages 309 through 312), but without the explanations that are between the code snippets:
class TCPOctetStream;
class TCPState;
class TCPConnection {
public:
	TCPConnection();
	
	void ActiveOpen();
	void PassiveOpen();
	void Close();
	void Send();
	void Acknowledge();
	void Synchronize();
	
	void ProcessOctet(TCPOctetStream*);
private:
	friend class TCPState;
	void ChangeState(TCPState*);
private:
	TCPState* _state;
};
{ ------------------------------------------------------------------ }
class TCPState {
public:
	virtual void Transmit(TCPConnection*, TCPOctetStream*);
	virtual void ActiveOpen(TCPConnection*);
	virtual void PassiveOpen(TCPConnection*);
	virtual void Close(TCPConnection*);
	virtual void Synchronize(TCPConnection*);
	virtual void Acknowledge(TCPConnection*);	
	virtual void Send(TCPConnection*);
protected:
	void ChangeState(TCPConnection*, TCPState*);
};
{ ------------------------------------------------------------------ }
TCPConnection::TCPConnection () {
	_state = TCPClosed::Instance();
}
void TCPConnection::ChangeState (TCPState* s) {
	_state = s;
}
void TCPConnection::ActiveOpen () {
	_state->ActiveOpen(this);
}
void TCPConnection::PassiveOpen () {
	_state->PassiveOpen(this);
}
void TCPConnection::Close () {
	_state->Close(this);
}
void TCPConnection::Acknowledge () {
	_state->Acknowledge(this);
}
void TCPConnection::Synchronize () {
	_state->Synchronize(this);
}
{ ------------------------------------------------------------------ }
void TCPState::Transmit(TCPConnection*, TCPOctetStream*) { }
void TCPState::ActiveOpen(TCPConnection*) { }
void TCPState::PassiveOpen(TCPConnection*) { }
void TCPState::Close(TCPConnection*) { }
void TCPState::Synchronize(TCPConnection*) { }
void TCPState::ChangeState (TCPConnection* t, TCPState* s) {
	t->ChangeState(s);
}
{ ------------------------------------------------------------------ }
class TCPEstablished : public TCPState {
public:
	static TCPState* Instance();
	
	virtual void Transmit(TCPConnection*, TCPOctetStream*);
	virtual void Close(TCPConnection*);
};
class TCPListen : public TCPState {
public:
	static TCPState* Instance();
	
	virtual void Send(TCPConnection*, TCPOctetStream*);
	// ...
};
class TCPClosed : public TCPState {
public:
	static TCPState* Instance();
	
	virtual void ActiveOpen(TCPConnection*);
	virtual void PassiveOpen(TCPConnection*);
	// ...
};
{ ------------------------------------------------------------------ }
void TCPClosed::ActiveOpen (TCPConnection* t) {
	// send SYN, receive SYN, ACK, etc.
	
	ChangeState(t, TCPEstablished::Instance());
}
void TCPClosed::PassiveOpen (TCPConnection* t) {
	ChangeState(t, TCPListen::Instance());
}
void TCPEstablished::Close (TCPConnection* t) {
	// send FIN, receive ACK of FIN
	
	ChangeState(t, TCPListen::Instance());
}
void TCPEstablished::Transmit (TCPConnection* t, TCPOctetStream* o) {
	t->ProcessOctet(o);
}
void TCPListen::Send (TCPConnection* t) {
	// send SYN, receive SYN, ACK, etc.
	
	ChangeState(t, TCPEstablished::Instance());
}
83.80.64.20 13:54, 15 September 2006 (UTC)
thread_title:  TCPConnection class the GoF book 

message: Consider this example of a state machine coded in Python. Don't try this at home in C++.
# State Machine example Program
from StateDefn import *
class MyMachine(object):
    # Create Statedefn object for each state you need to keep track of.
    # the name passed to the constructor becomes a StateVar member of 
    # the current class. e.g. if myObj is a MyMachine object and "gstate"
    # is the argument to the constructor, myObj.gstate becomes the instances
    # state variable.
    Gstate = StateTable("gstate")
    Tstate = StateTable("turtle")
    def __init__(self, name):
        # must call init method of class's StateTable object. to initialize state variable
        self.Gstate.initialize(self)
        self.Tstate.initialize(self)
        self.mname = name
        self.Acount = 0
        self.Bcount = 0
        self.Ccount = 0
    # Decorate the Event Handler virtual functions -note Gstate parameter
    @EventHandler(Gstate)
    def EventA( self ): pass
    @EventHandler(Gstate)
    def EventB( self ): pass
    @EventHandler(Gstate)
    def EventC( self, val ): pass
    @EventHandler(Tstate)
    def Toggle(self): pass
    # define methods to handle events.
    def _eventAHdlr1(self):
        print "State 1, event A"
        self.Acount += 1
    def _eventBHdlr1(self):
        print "State 1, event B"
        self.Bcount += 1
    def _eventCHdlr1(self, val):
        print "State 1, event C"
        self.Ccount += 3*val
    def _eventAHdlr2(self):
        print "State 2, event A"
        self.Acount += 10
    def _eventBHdlr2(self):
        print "State 2, event B"
        self.Bcount += 10
    def _eventCHdlr2(self, val):
        print "State 2, event C"
        self.Ccount += 2*val
    def _eventAHdlr3(self):
        self.Acount += 100
        print "State 3, event A"
    def _eventBHdlr3(self):
        print "State 3, event B"
        self.Bcount += 100
    def _eventCHdlr3(self, val):
        print "State 3, event C"
        self.Ccount += 5*val
    
    # Associate the handlers with a state. The first argument is the name of the 
    # state. The second argument is a list of methods.
    # One method for each EventHandler decorated function of Gstate. Order of methods
    # in the list correspond to order in which the Event Handlers were declared.
    # Third argument defines the states to transition into when event occurs.
    #
    # The first state created becomes the initial state.
    _state1 = Gstate.State("One",  (_eventAHdlr1, _eventBHdlr1, _eventCHdlr1 ), 
                                      ("Two", "Three", None ))
    _state2 = Gstate.State("Two",  (_eventAHdlr2, _eventBHdlr2, _eventCHdlr2 ),
                                     ("Three",        None,          "One"))
    _state3 = Gstate.State("Three",(_eventAHdlr3, _eventBHdlr3, _eventCHdlr3 ),
                                 (None,         "One",         "Two"))
    # Declare a function that will be called when entering a new Gstate.
    # Can also declare a leave function using @OnLeaveFunction(Gstate)
    @OnEnterFunction(Gstate)
    def _enterGstate(self):
        print "entering state ", self.gstate.Name() , "of ", self.mname
    @OnLeaveFunction(Tstate)
    def _leaveTstate(self):
        print "leaving state ", self.turtle.Name() , "of ", self.mname
    def _toggleOn(self):
        print "Toggle On"
    def _toggleOff(self):
        print "Toggle Off"
    _t_off = Tstate.State( "Off", [_toggleOn],
                         ["On"     ])
    _t_on =  Tstate.State( "On",  [_toggleOff],
                          ["Off"])
def main():
    bigMachine = MyMachine("big")
    bigMachine.EventA()
    bigMachine.EventA()
    bigMachine.EventB()
    bigMachine.EventC(4)
    bigMachine.EventA()
    bigMachine.Toggle()
    bigMachine.Toggle()
    bigMachine.Toggle()
    bigMachine.EventC(7)
 
    print "Event A count ", bigMachine.Acount
    print "Event B count ", bigMachine.Bcount
    print "Event C count ", bigMachine.Ccount
main()
--64.238.49.65 23:19, 21 March 2007 (UTC)
thread_title:  Example in Python 

message: I agree this is an example of a strategy pattern. Even if those two are quire related (a well used state is a form of strategy and is not limited to a simple enumeration as it is too often encountered), the pattern state still holds the semantic of internal modifications, and obviously the "state" semantic which is totally absent here, even if extended to the extreme.
This example should be swapped by a correct and meaningful one, requiring not much background, like the traditional online/offline behavior, or the scholar "connexion state" code fragment.
Tobei 10:16, 13 August 2007 (UTC)
thread_title:  Strategy