#include <iostream>
using namespace std;
#define DESTROY_POINTER(ptr) if (ptr) { delete ptr; ptr = NULL; }
class Context;
class DbState
{
public:
DbState(Context* pContext) { m_pContext = pContext; }
virtual void Open()=;
virtual void Close()=;
virtual void Read()=;
virtual void Write()=;
protected:
Context* m_pContext;
};
class OpenState : public DbState
{
public:
OpenState(Context* pContext) : DbState(pContext) {}
void Open() { cout<<"Already open!"<<endl; }
void Close();
void Read() { cout<<"Finish Reading"<<endl; }
void Write() { cout<<"Finish Writing"<<endl; }
};
class CloseState : public DbState
{
public:
CloseState(Context* pContext) : DbState(pContext) {}
void Open();
void Close() { cout<<"Already Closing"<<endl; }
void Read() { cout<<"Already Closing, Can't read"<<endl; }
void Write() { cout<<"Already Closing, Can't write"<<endl; }
};
class ReadingState : public DbState
{
public:
ReadingState(Context* pContext) : DbState(pContext) {}
void Open() { cout<<"Already Open"<<endl; }
void Close();
void Read() { cout<<"Reading, Try again"<<endl; }
void Write() { cout<<"Reading, Can't write"<<endl; }
};
class WritingState : public DbState
{
public:
WritingState(Context* pContext) : DbState(pContext) {}
void Open() { cout<<"Already Open"<<endl; }
void Close();
void Read() { cout<<"Writing, Can't read"<<endl; }
void Write() { cout<<"Writing, Try again"<<endl; }
};
class BusyState : public DbState
{
public:
BusyState(Context* pContext) : DbState(pContext) {}
void Open() { cout<<"Already Open"<<endl; }
void Close() { cout<<"Busy, Can't Close"<<endl; }
void Read() { cout<<"Busy, Can't read"<<endl; }
void Write() { cout<<"Busy, Can't write"<<endl; }
};
class Context
{
public:
Context() : m_pState(NULL) {}
~Context() { DESTROY_POINTER(m_pState); }
void SetState(DbState* pState) { DESTROY_POINTER(m_pState); m_pState = pState; }
void Open() { m_pState->Open(); }
void Close() { m_pState->Close(); }
void Read() { m_pState->Read(); }
void Write() { m_pState->Write(); }
private:
DbState* m_pState;
};
void OpenState::Close() { cout<<"Finish closing"<<endl; m_pContext->SetState(new CloseState(m_pContext)); }
void CloseState::Open() { cout<<"Finish Opening"<<endl; m_pContext->SetState(new OpenState(m_pContext)); }
void ReadingState::Close() { cout<<"Finish Closing"<<endl; m_pContext->SetState(new CloseState(m_pContext)); }
void WritingState::Close() { cout<<"Finish Closing"<<endl; m_pContext->SetState(new CloseState(m_pContext)); }
int main(int argc, char *argv[])
{
Context context;
context.SetState(new OpenState(&context));
context.Open();
context.Close();
context.Open();
context.Read();
context.Write();
context.Close();
context.Write();
context.Open();
context.Write();
return ;
}