336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
** 패턴 그리고 객체지향적 코딩의 법칙 - Story 22_ 난 기분에 따라 행동이 달라져 **
위 책의 스테이트 패턴 부분을 코딩해 보았습니다.
나머지 패턴은 이해가 그나마 갔는데 스테이트 패턴이라는게 이해 하기도 어렵고 코딩 하기도 힘들군요.
결국엔 공통된 Interface를 뽑아내고 하나의 클래스에 하나의 책임을 진다는 명제하의 개념이긴 하지만..
실제 업무에 적용 하려면 일단 그림을 그려서 파악하는게 우선이라고 생각이 듭니다.
아래 code들은 실제 server랑 client 통신에 적용 시켜서 해봐야 겠지만.. 일단은 개념을 잡기 위해서 가상으로 main 함수에서 구현을 해 보았네요
일단은 정리 해 놓고 차츰 추가로 UML이나 동작 원리에 대해서는 차후에 추가 해야겠습니다.
** ISPGPContext.h
** CSPGLayer.h
** CSPGPState.h
** CSPGClient.h
** main.cpp
위 책의 스테이트 패턴 부분을 코딩해 보았습니다.
나머지 패턴은 이해가 그나마 갔는데 스테이트 패턴이라는게 이해 하기도 어렵고 코딩 하기도 힘들군요.
결국엔 공통된 Interface를 뽑아내고 하나의 클래스에 하나의 책임을 진다는 명제하의 개념이긴 하지만..
실제 업무에 적용 하려면 일단 그림을 그려서 파악하는게 우선이라고 생각이 듭니다.
아래 code들은 실제 server랑 client 통신에 적용 시켜서 해봐야 겠지만.. 일단은 개념을 잡기 위해서 가상으로 main 함수에서 구현을 해 보았네요
일단은 정리 해 놓고 차츰 추가로 UML이나 동작 원리에 대해서는 차후에 추가 해야겠습니다.
** ISPGPContext.h
#ifndef __ISPGPCONTEXT_H_ #define __ISPGPCONTEXT_H_ #include "CSPGPState.h" class ISPGPContext { public: virtual void ChangeState(CSPGPState* a_pNextState) = 0; }; #endif
** CSPGLayer.h
#ifndef __CSPGPLAYER_H_ #define __CSPGPLAYER_H_ #include#include "ISPGPContext.h" #include "CSPGPState.h" #include "CSPGClient.h" using namespace std; class CSPGLayer : public ISPGPContext { public: CSPGLayer() { m_pState = new CSPGClientHello; m_pState->SetContext(this); } ~CSPGLayer() { if (m_pState) delete m_pState; } void ChangeState(CSPGPState* a_pNextState) { if (m_pState) { delete m_pState; m_pState = NULL; } a_pNextState->SetContext(this); m_pState = a_pNextState; } public: void Send() { char aBuf[4096] = {0, }; int nUsedSize = 0; ESPGP_ERR eReturn; do { int nUsedSize = 0; eReturn = m_pState->Send(aBuf, 4096, &nUsedSize); if (nUsedSize > 0) { } } while (eReturn == eSPGPG_ERR_SEND); if (eReturn != eSPGPG_ERR_SUCCESS) { /* Close() */ } } void OnReceive (char* a_pBuf, int a_nBufSize) { char* pCurBuf = a_pBuf; int nCurBufSize = a_nBufSize; int nUsedSize = 0; ESPGP_ERR eReturn; do { int nUsedSize = 0; eReturn = m_pState->Receive(pCurBuf, nCurBufSize, &nUsedSize); if (nUsedSize > 0) { pCurBuf += nUsedSize; nCurBufSize -= nUsedSize; } } while (eReturn == eSPGPG_ERR_RECEIVE); cout << "[CSPGLayer::OnReceive] " << a_pBuf << "를 " << a_nBufSize <<" byte 만큼 서버로부터 받았습니다." << endl<< endl; switch (eReturn) { case eSPGPG_ERR_SEND: Send(); break; case eSPGPG_ERR_SUCCESS: /* Close() */ break; } } private: CSPGPState* m_pState; // 현재 상태 객체 }; #endif
** CSPGPState.h
#ifndef __CSPGPSSTATE_H_ #define __CSPGPSSTATE_H_ typedef enum{ eSPGPG_ERR_SUCCESS, eSPGPG_ERR_FAIL, eSPGPG_ERR_SEND, eSPGPG_ERR_RECEIVE }ESPGP_ERR; class ISPGPContext; class CSPGPState /* ISPGPState */ { public: virtual ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) = 0; virtual ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) = 0; public: void SetContext (ISPGPContext* a_pContext) { m_pContext = a_pContext; } protected: ISPGPContext* m_pContext; }; #endif
** CSPGClient.h
#ifndef __CSPGCLIENT_H_ #define __CSPGCLIENT_H_ #include#include #include "CSPGPState.h" using namespace std; class CSPGClientFinish : public CSPGPState { public: ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { strcpy(a_pBuf, "Clent Finish Info"); *a_pnUsedSize = strlen("Clent Finish Info"); cout << "[CSPGClientFinish::Send]" << endl; cout << "[CSPGClientFinish::Send] " << a_pBuf << "를 " << *a_pnUsedSize <<" byte 만큼 서버로 보냅니다" << endl<< endl; return eSPGPG_ERR_SUCCESS; } ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { cout << "[CSPGClientFinish::Receive]" << endl; return eSPGPG_ERR_SUCCESS; } }; class CSPGClientInfo : public CSPGPState { public: ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { strcpy(a_pBuf, "Clent Info"); *a_pnUsedSize = strlen("Clent Info"); cout << "[CSPGClientInfo::Send]" << endl; cout << "[CSPGClientInfo::Send] " << a_pBuf << "를 " << *a_pnUsedSize <<" byte 만큼 서버로 보냅니다" << endl<< endl; m_pContext->ChangeState(new CSPGClientFinish); return eSPGPG_ERR_SUCCESS; } ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { return eSPGPG_ERR_FAIL; } }; class CSPGServerInfo : public CSPGPState { public: ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { return eSPGPG_ERR_FAIL; } ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { cout << "[CSPGServerInfo::Receive]" << endl; m_pContext->ChangeState(new CSPGClientInfo); return eSPGPG_ERR_SEND; } }; class CSPGServerHello : public CSPGPState { public: ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { return eSPGPG_ERR_FAIL; } ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { cout << "[CSPGServerHello::CSPGPState]" << endl; m_pContext->ChangeState(new CSPGServerInfo); return eSPGPG_ERR_SUCCESS; } }; class CSPGClientHello : public CSPGPState { public: ESPGP_ERR Send(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { strcpy(a_pBuf, "Hello"); *a_pnUsedSize = strlen("Hello"); cout << "[CSPGClientHello::Send]" << endl; cout << "[CSPGClientHello::Send] " << a_pBuf << "를 " << *a_pnUsedSize <<" byte 만큼 서버로 보냅니다" << endl<< endl; m_pContext->ChangeState(new CSPGServerHello); return eSPGPG_ERR_SUCCESS; } ESPGP_ERR Receive(char* a_pBuf, int a_nBufSize, int* a_pnUsedSize) { return eSPGPG_ERR_FAIL; } }; #endif
** main.cpp
CSPGLayer layer; layer.Send(); layer.OnReceive("Hello", strlen("Hello")); layer.OnReceive("Server info", strlen("Server info")); layer.Send(); layer.OnReceive("Server Finish", strlen("Server Finish"));
'ⓟrogramming > Design Pattern' 카테고리의 다른 글
[아임구루] Design Pattern 3일차 (0) | 2016.02.17 |
---|---|
[아임구루] Design Patter 2일차 (0) | 2016.02.16 |
[아임구루] Design Pattern 1일차 (0) | 2016.02.15 |
Decorator(데코레이터) pattern (0) | 2011.02.28 |
Command(커멘드) Pattern (0) | 2011.02.28 |