State Design pattern allows an object to change it's behavior based on its internal State.The Object will appear to change its class.
State Design Pattern in C++ to implement state machine of a Music Player System.
classes used:
MusicSystem -> is the current state context manager class.
State -> is the base class of all states classes.
OFFState -> is the concrete class derived from State.
ONState -> is the concrete class derived from State.
PAUSEDState ->is the concrete class derived from State.
Example:
#include<iostream>
using namespace std;
//current_context class
class State;
class MusicSystem
{
private:
State *currentState;//to store current state.
public:
enum statesEnum
{
ST_STOPPED,
ST_PLAYING,
ST_PAUSEDState
};
public:
MusicSystem();
void stopMusic();
void playMusic();
void playNextTrack();
void playPreviousTrack();
void pauseMusic();
void setCurrentContext(statesEnum state);
};
//abstract state class
class State
{
public:
//MusicSystem's pointer is passed so that setCurrentState can be called.
virtual void off(MusicSystem *ms){cout<<"Already Stopped."<<endl;}
virtual void play(MusicSystem* ms){cout<<"Already Playing."<<endl;}
virtual void playNextTrack(MusicSystem* ms){cout<<"Can not play Next in off/paused state."<<endl;}
virtual void playPreviousTrack(MusicSystem* ms){cout<<"Can not play Previous in off/paused state."<<endl;}
virtual void pause(MusicSystem* ms){cout<<"Can not Switch to pause in stopped state."<<endl;}
};
//concrete state class on
class OFFState:public State
{
public:
void play(MusicSystem *ms);
};
//concrete state class off
class ONState:public State
{
public:
void off(MusicSystem *ms);
void playNextTrack(MusicSystem *ms);
void playPreviousTrack(MusicSystem *ms);
void pause(MusicSystem* ms);
};
//concrete class pause
class PAUSEDState:public State
{
public:
void off(MusicSystem *ms);
void playNextTrack(MusicSystem *ms);
void playPreviousTrack(MusicSystem *ms);
void play(MusicSystem* ms);
};
MusicSystem::MusicSystem()
{
currentState=new OFFState;
}
void MusicSystem::stopMusic()
{
currentState->off(this);
}
void MusicSystem::playMusic()
{
currentState->play(this);
}
void MusicSystem::playNextTrack()
{
currentState->playNextTrack(this);
}
void MusicSystem::playPreviousTrack()
{
currentState->playPreviousTrack(this);
}
void MusicSystem::pauseMusic()
{
currentState->pause(this);
}
void OFFState::play(MusicSystem *ms)
{
cout<<"Turning to Play."<<endl;
ms->setCurrentContext(MusicSystem::ST_PLAYING);
delete this;
}
void ONState::off(MusicSystem *ms)
{
cout<<"Turning to Stopped."<<endl;
ms->setCurrentContext(MusicSystem::ST_STOPPED);
delete this;
}
void ONState::playNextTrack(MusicSystem *ms)
{
cout<<"Playing next track..."<<endl;
}
void ONState::playPreviousTrack(MusicSystem *ms)
{
cout<<"Playing previous track..."<<endl;
}
void ONState::pause(MusicSystem* ms)
{
cout<<"Switching to Pause."<<endl;
ms->setCurrentContext(MusicSystem::ST_PAUSEDState);
}
void PAUSEDState::off(MusicSystem *ms)
{
cout<<"Turning to Stopped."<<endl;
ms->setCurrentContext(MusicSystem::ST_STOPPED);
delete this;
}
void PAUSEDState::playNextTrack(MusicSystem *ms)
{
cout<<"Playing next track..."<<endl;
}
void PAUSEDState::playPreviousTrack(MusicSystem *ms)
{
cout<<"Playing previous track..."<<endl;
}
void PAUSEDState::play(MusicSystem* ms)
{
cout<<"Switching to Play."<<endl;
ms->setCurrentContext(MusicSystem::ST_PLAYING);
}
void MusicSystem::setCurrentContext(statesEnum state)
{
if(state==ST_STOPPED)
{
currentState=new OFFState;
}
else if(state == ST_PLAYING)
{
currentState=new ONState();
}
else if(state == ST_PAUSEDState)
{
currentState=new PAUSEDState();
}
else
{
cout<<"Unknown state"<<endl;
}
}
//main
int main()
{
MusicSystem ms;
ms.MusicSystem::stopMusic();
ms.MusicSystem::stopMusic();
ms.MusicSystem::pauseMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
ms.MusicSystem::playMusic();
ms.MusicSystem::playMusic();
ms.MusicSystem::pauseMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
ms.MusicSystem::stopMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
return 0;
}
/*
Already Stopped.
Already Stopped.
Can not Switch to pause in stopped state.
Can not play Next in off/paused state.
Can not play Previous in off/paused state.
Turning to Play.
Already Playing.
Switching to Pause.
Playing next track...
Playing previous track...
Turning to Stopped.
Can not play Next in off/paused state.
Can not play Previous in off/paused state.
*/
State Design Pattern in C++ to implement state machine of a Music Player System.
classes used:
MusicSystem -> is the current state context manager class.
State -> is the base class of all states classes.
OFFState -> is the concrete class derived from State.
ONState -> is the concrete class derived from State.
PAUSEDState ->is the concrete class derived from State.
Example:
#include<iostream>
using namespace std;
//current_context class
class State;
class MusicSystem
{
private:
State *currentState;//to store current state.
public:
enum statesEnum
{
ST_STOPPED,
ST_PLAYING,
ST_PAUSEDState
};
public:
MusicSystem();
void stopMusic();
void playMusic();
void playNextTrack();
void playPreviousTrack();
void pauseMusic();
void setCurrentContext(statesEnum state);
};
//abstract state class
class State
{
public:
//MusicSystem's pointer is passed so that setCurrentState can be called.
virtual void off(MusicSystem *ms){cout<<"Already Stopped."<<endl;}
virtual void play(MusicSystem* ms){cout<<"Already Playing."<<endl;}
virtual void playNextTrack(MusicSystem* ms){cout<<"Can not play Next in off/paused state."<<endl;}
virtual void playPreviousTrack(MusicSystem* ms){cout<<"Can not play Previous in off/paused state."<<endl;}
virtual void pause(MusicSystem* ms){cout<<"Can not Switch to pause in stopped state."<<endl;}
};
//concrete state class on
class OFFState:public State
{
public:
void play(MusicSystem *ms);
};
//concrete state class off
class ONState:public State
{
public:
void off(MusicSystem *ms);
void playNextTrack(MusicSystem *ms);
void playPreviousTrack(MusicSystem *ms);
void pause(MusicSystem* ms);
};
//concrete class pause
class PAUSEDState:public State
{
public:
void off(MusicSystem *ms);
void playNextTrack(MusicSystem *ms);
void playPreviousTrack(MusicSystem *ms);
void play(MusicSystem* ms);
};
MusicSystem::MusicSystem()
{
currentState=new OFFState;
}
void MusicSystem::stopMusic()
{
currentState->off(this);
}
void MusicSystem::playMusic()
{
currentState->play(this);
}
void MusicSystem::playNextTrack()
{
currentState->playNextTrack(this);
}
void MusicSystem::playPreviousTrack()
{
currentState->playPreviousTrack(this);
}
void MusicSystem::pauseMusic()
{
currentState->pause(this);
}
void OFFState::play(MusicSystem *ms)
{
cout<<"Turning to Play."<<endl;
ms->setCurrentContext(MusicSystem::ST_PLAYING);
delete this;
}
void ONState::off(MusicSystem *ms)
{
cout<<"Turning to Stopped."<<endl;
ms->setCurrentContext(MusicSystem::ST_STOPPED);
delete this;
}
void ONState::playNextTrack(MusicSystem *ms)
{
cout<<"Playing next track..."<<endl;
}
void ONState::playPreviousTrack(MusicSystem *ms)
{
cout<<"Playing previous track..."<<endl;
}
void ONState::pause(MusicSystem* ms)
{
cout<<"Switching to Pause."<<endl;
ms->setCurrentContext(MusicSystem::ST_PAUSEDState);
}
void PAUSEDState::off(MusicSystem *ms)
{
cout<<"Turning to Stopped."<<endl;
ms->setCurrentContext(MusicSystem::ST_STOPPED);
delete this;
}
void PAUSEDState::playNextTrack(MusicSystem *ms)
{
cout<<"Playing next track..."<<endl;
}
void PAUSEDState::playPreviousTrack(MusicSystem *ms)
{
cout<<"Playing previous track..."<<endl;
}
void PAUSEDState::play(MusicSystem* ms)
{
cout<<"Switching to Play."<<endl;
ms->setCurrentContext(MusicSystem::ST_PLAYING);
}
void MusicSystem::setCurrentContext(statesEnum state)
{
if(state==ST_STOPPED)
{
currentState=new OFFState;
}
else if(state == ST_PLAYING)
{
currentState=new ONState();
}
else if(state == ST_PAUSEDState)
{
currentState=new PAUSEDState();
}
else
{
cout<<"Unknown state"<<endl;
}
}
//main
int main()
{
MusicSystem ms;
ms.MusicSystem::stopMusic();
ms.MusicSystem::stopMusic();
ms.MusicSystem::pauseMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
ms.MusicSystem::playMusic();
ms.MusicSystem::playMusic();
ms.MusicSystem::pauseMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
ms.MusicSystem::stopMusic();
ms.MusicSystem::playNextTrack();
ms.MusicSystem::playPreviousTrack();
return 0;
}
/*
Already Stopped.
Already Stopped.
Can not Switch to pause in stopped state.
Can not play Next in off/paused state.
Can not play Previous in off/paused state.
Turning to Play.
Already Playing.
Switching to Pause.
Playing next track...
Playing previous track...
Turning to Stopped.
Can not play Next in off/paused state.
Can not play Previous in off/paused state.
*/