• Articles
  • Using the Design Pattern State, for the
Published by
Dec 28, 2014 (last update: Jan 16, 2015)

Using the Design Pattern State, for the Simple Problem of the Semaphore

Score: 3.8/5 (146 votes)
*****
Again, IDE CodeGear C++Builder 2007

  • Download source code - 6.18 KB


  • Introduction

    In this article I explain the use of the State Design Pattern, using good programming practices. Drawing on a simple problem that we can develop at different time intervals, the semaphore.



    Pattern State

    It is conceived as one of the Patterns of Behavior, basically admits that transforms any object behavior because its status changes.


    Here we can see the class diagram of Pattern State, using appropriate names of class.



    In the diagram the various participants can have and its definition are presented.


    • Context | TLNetTraffic : This class can contain different states.

    • State | TLState : Defines a common Interface or Abstract Class for all concrete states, always implementing the same interface or abstracting the same class.

    • ConcreteState | TL {Red, Yellow, Green} : For each particular state implements a behavior associated with a state of the context.


    Implementation

    We must have sufficient and necessary knowledge of OOP, and most of all pointers.


    ...we define our Context Class, look, that it starts in the Red Light state:


    ¨TLNetTraffic.h¨
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class TLNetTraffic
    {
    	private:
    		TLState* _state;
    	public:
    		TLNetTraffic();
    		void setState ( TLState* state );
    		void Handle();
    };


    ¨TLNetTraffic.cpp¨
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    TLNetTraffic::TLNetTraffic()
    {
    	_state = new TLRed(this);
    }
    
    void TLNetTraffic::setState ( TLState* state )
    {
    	_state = state;
    }
    
    void TLNetTraffic::Handle ()
    {
    	_state->Handle();
    }


    ...common to all states that can be implemented, abstract class, using the Handle() method as changing states should be overwritten by derived classes:


    ¨TLState.h¨
    1
    2
    3
    4
    5
    class TLState
    {
      public:
    	 virtual void Handle() = 0;
    };


    ...certainly, each state separately, see that the implementation is the same for all three state but not always will be, everything depends on the implementation that is needed for each state:

    ¨TLRed.h¨
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class TLRed: public TLState
    {
    	private:
    		TLNetTraffic* _context;
    
    	public:
    		TLRed(TLNetTraffic* context);
    		void Handle();
    };


    ¨TLRed.cpp¨
    1
    2
    3
    4
    5
    6
    7
    TLRed::TLRed(TLNetTraffic* context): _context(context) {};
    
    void TLRed::Handle()
    {
    	printf("Red Light\n");
    	_context->setState( new TLGreen(_context) );
    }



    ¨TLGreen.h¨
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class TLGreen: public TLState
    {
    	private:
    		TLNetTraffic* _context;
    
    	public:
    		TLGreen(TLNetTraffic* context);
    		void Handle();
    };


    ¨TLGreen.cpp¨
    1
    2
    3
    4
    5
    6
    7
    TLGreen::TLGreen(TLNetTraffic* context): _context(context) {};
    
    void TLGreen::Handle()
    {
    	printf("Green Light\n");
    	_context->setState( new TLYellow(_context) );
    }



    ¨TLYellow.h¨
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class TLYellow: public TLState
    {
    	private:
    		TLNetTraffic* _context;
    
    	public:
    		TLYellow(TLNetTraffic* context);
    		void Handle();
    };


    ¨TLYellow.cpp¨
    1
    2
    3
    4
    5
    6
    7
    TLYellow::TLYellow(TLNetTraffic* context): _context(context) {};
    
    void TLYellow::Handle()
    {
    	printf("Yellow Light\n");
    	_context->setState( new TLRed(_context) );
    }




    ...again, the main function. We use the library <time.h> for state changes in time intervals.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    int main (int argc, char* argv[])
    {
    	TLNetTraffic netTraffic;
    
    	int count = 0, i=0;
    	int seconds;
    
    	while(1)
    	{
    	   if (i%3==0) 
    		  printf("---------\nSession %d\n---------\n", ((i+1)/3)+1 );
    		   
    	   if (count == 0) seconds =6, count = 1;
    		   else if (count == 1) seconds = 4, count = 2;
    			   else if (count == 2) seconds = 5, count = 0;
    
    	   sleep( (clock_t)seconds * CLOCKS_PER_SEC );
    	   netTraffic.Handle();
    	   i++;
    	}
    	return 0;
    }



    The essential idea is to change the states of light at time intervals {RedLight (6 sec), GreenLight (4 sec), YellowLight (5 sec)} infinitely normally functioning traffic lights any road, perhaps used some data may not be accurate.


    ...and without fail, the sleep() function, which keeps the time instants at each iteration:

    1
    2
    3
    4
    5
    6
    void sleep( clock_t wait )
    {
       clock_t goal;
       goal = wait + clock();
       while( goal > clock() );
    }


    Will produces ouput:

    
    ---------
    Session 1
    ---------
    Red Light
    Green Light
    Yellow Light
    ---------
    Session 2
    ---------
    Red Light
    Green Light
    Yellow Light
    ---------
    Session 3
    ---------
    … and so on
    


    Conclusion

    Proper use of various feedback and Design Patterns already defined should be used in all that is program today. In the implementation we have here a problem solved by using patterns and skills can be evidenced. Fortunately, I continue to work for everyone.



    Bibliography recommended on Design Patterns

    • Steve Holzner, PhD. (2006). Design Patterns for Dummies.

    • Eric Freeman, Elizabeth Freeman, Kathy Sierra, Bert Bates. (2004). Your Brain on Design Patterns Head First Design Patterns.

    • James W. Cooper. (2000). JAVATM Design Patterns : A Tutorial.

    • Erich Gamma, Richard Helm, Ralph Johnson, Jhon Vlissides. (1998). Design Patterns. Gang of Four.