상세 컨텐츠

본문 제목

상태 패턴

프로그래밍 관련/패턴

by AlrepondTech 2010. 3. 26. 11:14

본문

반응형


상태 패턴 다이어그램





저도 강좌라는걸 써보네요..;;

 

디자인 패턴중 상태패턴에 대해 간단하게 설명해 보려고 합니다.

 

보통 상태패턴( State Pattern )은 'Object의 속성을 다른 객체에 위임한다' 라 되어 있으며,

구현 목적은 '다른 종류의 객체들이 공통 속성을 가지는 경우, 속성의 구현을 포함하는 객체에서 분리시킨다'

 

라고 되어 있습니다.

 

따라서 구현을 위해서는  속성을 가진 객체와 실제 속성을 구현하려는 객체가 필요합니다.

 

 

좀더 쉽게 말하면, A, B, C 라는 객체가 있는데,

 

Move, Attack, Guard, Stop 등  공통되는 구현이 있다면,

 

이러한 액션을 취하는 속성들을 따로 분리해서, 구현한다는게 상태패턴의 목적입니다.

 

그럼, 소스 위주로 설명하겠습니다.


#include <stdio.h>
#include <iostream.h>


#define SAFE_DELETE( p ) { if(p) { delete(p); p = NULL; } }

#define NEXTLINE printf("\n\n");

 

/*---------------------------------------------------------------------------------------------------------*/

class CAction
{

protected:
 
 enum ACTION_ID { ACT_MOVE, ACT_STOP, ACT_ATTACK, ACT_GUARD };

 const ACTION_ID m_actionID;

public:

 CAction( ACTION_ID actID ) : m_actionID(actID) {}
 ~CAction() {}

 virtual void Action() = 0;


// void printActionID()
// {
//  switch( m_actionID )
//  {
//   case ACT_MOVE:  printf(" [A] CAtion: ACT_MOVE\n");  break;
//   case ACT_STOP:  printf(" [A] CAtion: ACT_STOP\n");  break;
//   case ACT_ATTACK: printf(" [A] CAtion: ACT_ATTACK\n"); break;
//   case ACT_GUARD:  printf(" [A] CAtion: ACT_GUARD\n");  break;
//  }
// }


};

/*---------------------------------------------------------------------------------------------------------*/


class CAction_Move : public CAction
{
public:
 
 CAction_Move(): CAction( ACT_MOVE ) { printf( "--이동모드 설정완료\n" ); }
 ~CAction_Move();

 void Action()
 {
  printf( "--> 이동!!\n" );
 }
};

/*---------------------------------------------------------------------------------------------------------*/


class CAction_Stop : public CAction
{
public:

 CAction_Stop(): CAction( ACT_STOP ) { printf( "--정지모드 설정완료\n" ); }
 ~CAction_Stop();

 void Action()
 {
  printf( "--> 정지!!\n" );
 }
 
};

/*---------------------------------------------------------------------------------------------------------*/


class CAction_Attack : public CAction
{
public:

 CAction_Attack(): CAction( ACT_ATTACK ) { printf( "--공격모드 설정완료\n" ); }
 ~CAction_Attack();

 void Action()
 {
  printf( "--> 공격!!\n" );
 }
 
};

/*---------------------------------------------------------------------------------------------------------*/


class CAction_Guard : public CAction
{
public:

 CAction_Guard(): CAction( ACT_GUARD ) { printf( "--방어모드 설정완료\n" ); }
 ~CAction_Guard();

 void Action()
 {
  printf( "--> 방어!!\n" );
 }
 
};

/*---------------------------------------------------------------------------------------------------------*/

 

CAction을 상속받은 각 4개의 액션클래스를 구현을 합니다.

 


 

#include "Action.h"

 

 


class CMarine
{

protected:

 CAction* m_pAction;
 
 void ChangeAction( CAction* pNewAction )
 {
  SAFE_DELETE( m_pAction );
  m_pAction = pNewAction;
 }


public:

 CMarine() 
 {
  printf( "마린생성!!\n" );
  m_pAction = NULL;
  State_Stop();
 }

 CMarine( CAction* pNewAction )
 {
  printf( "마린(액션)생성!!\n" );
  m_pAction = pNewAction;
 }

 ~CMarine()
 {
  printf( "마린제거!!\n" );
  SAFE_DELETE( m_pAction );
 }

 void Update() { m_pAction->Action(); }

 void State_Move() { ChangeAction( new CAction_Move );  }
 void State_Stop() { ChangeAction( new CAction_Stop );  }
 void State_Attack() { ChangeAction( new CAction_Attack); }
 void State_Guard() { ChangeAction( new CAction_Guard);  }
 


};

 

마린 클래스에는 액션클래스 포인터를 내포하고 있으며,

 

상태를 변경할때마다, 액션클래스를 생성및 제거를 합니다.

 

 

 


#include "Marine.h"


#define PLAYER_NUM 3


void main()
{
 printf("\n== main() Start ===============================================\n\n");

 CMarine* pPlayerList[PLAYER_NUM];

 pPlayerList[0] = new CMarine();
 pPlayerList[1] = new CMarine();
 pPlayerList[2] = new CMarine();   // 마린 3마리 생성


 NEXTLINE;
 for( int i=0; i<PLAYER_NUM; i++ )
  pPlayerList[i]->Update();   // 마린 업데이트

 NEXTLINE;
 pPlayerList[0]->State_Move();
 pPlayerList[1]->State_Attack();
 pPlayerList[2]->State_Guard();   // 마린 설정 변경


 NEXTLINE;
 for( i=0; i<PLAYER_NUM; i++ )
  pPlayerList[i]->Update();   // 마린 업데이트


 NEXTLINE;
 for( i=0; i<PLAYER_NUM; i++ )
  delete pPlayerList[i];    // 마린 삭제


 NEXTLINE;
 printf( "\n== main() and =================================================\n\n" );

}

 

 

 메인부분입니다.

 

마린 3마리를 생성한다음, 업데이트 시킵니다.

 

초기화가 STOP으로 되어 있으니까, 가만히 서있겠네요..

 

그다음 각각 다른 명령을 내려준다음, 업데이트 시킵니다.

 

어느놈은 그냥, 이동하고, 다른놈은 공격하러 가고 각기 다르게 움직이겠네요..

 

공격하러간 마린이 러커나 저글링에게 죽게 되면, 삭제를 합니다.

 

 

 

개인적으로 이 상태패턴이야 말로, 클래스의 상속기능을 제대로 활용하는 방법중 하나라고 생각합니다.

 

문제는 상태가 실시간으로 자주 변할경우, 메모리 할당과 삭제가 많으므로, 단편화 문제가 있는데,

 

이는 메모리 풀로 해결을 하면 됩니다.

 

디자인 패턴의 목적이 성능을 높이기 보다는, 디자인의 유연성을 높이는것인 만큼,

 

그 상황에 맞게 적절히 사용한다면, 유지보수및 코딩하기가 더 수월해질 거라 생각합니다.

 

그럼.. 즐코딩~

 
 출처: http://cafe.naver.com/jzsdn/4808

 

반응형

'프로그래밍 관련 > 패턴' 카테고리의 다른 글

팩토리 패턴  (0) 2010.04.28
이터레이터 패턴 (Iterator Pattern)  (0) 2010.03.26


관련글 더보기

댓글 영역