디자인 패턴 - IV

그림자왕국·2022년 1월 16일
1

Design Patterns

목록 보기
4/5

상태 패턴

상태 패턴(state pattern)은 객체 지향 방식으로 상태 기계를 구현하는 행위 소프트웨어 디자인 패턴이다. 상태 패턴을 이용하면 상태 패턴 인터페이스의 파생 클래스로서 각각의 상태를 구현함으로써, 또 패턴의 슈퍼클래스에 의해 정의되는 메소드를 호출하여 상태 변화를 구현함으로써 상태 기계를 구현한다.

상태 인터페이스

class HeroineState {
 public: 
  virtual ~HeroineState() {} 
  virtual HeroineState* handleInput(Heroien& heroine, Input input) {} 
  virtual void update(Heroien& heroine) {} 
};

class DuckingState : public HeroineState { 
 public:
  virtual HeroineState* handleInput(Heroien& heroine, Input input) override {
   if(input == RELEASE_DOWN) 
    return new StandingState(); // 다른 파생형 클래스(상태)로 전환
   else 
    return NULL; // 지금 상태를 유지한다.
  } 
}

class StandingState : public HeroineState {
 public :
  virtual HeroineState* handleInput(Heroine& heroine, Input input) override {
  if(input == PRESS_DOWN) 
   return new DuckingState(); // 현재 상태(Standing)를 Ducking 상태로 전이
  else 
   return NULL; // 지금 상태를 유지한다.
  }
}

상태 인터페이스의 파생형 클래스는 각 상태를 정의하는 클래스다. 이 파생 클래스를 전환해가며
상태 객체 Heroine의 상태를 전환할 수 있다.

상태(HeroineState)를 가지는 캐릭터 클래스

class Heroine { 
 public: 
  virtual void handleInput(Input input) { state_->handleInput(*this, input); } 
  virtual void update() { state_->update(*this); } 
 private: 
  HeroineState* state_; 
};

상태 객체를 새롭게 할당하는 법

상태를 바꾸려면 state_에 새로운 상태 객체를 할당해야 한다.
상태가 전이할 때마다 상태 객체를 만들면 FSM이 상태별로 인스턴스를 갖게 된다.

void Heroine::handleInput(Input input) { 
 HeroineState* state = sate_->handleInput(*this, input); // ※ 새로운 상태의 반환을 시도
 if(state != NULL) { 
  delete state_; // 새로 상태를 할당하기 때문에 이전 상태를 힙에서 해제해야 한다.
  state_ = state; // 상태 전환
 } 
}

정리

Heroine 클래스의 handleInput 메서드가 새로운 상태를 반환하지 않는다면 현재 상태를 삭제하지 않고 유지한다. (return NULL)

이는 잘못된 키 입력이나 키 입력을 하지 않았을 경우 NULL이 반환되어 현재 상태가 유지된다.

서 있기 상태(Standing)에서 엎드리기 상태(Ducking)로 전이하려면 새로운 인스턴스를 생성해(new DuckingState()) 상태를 반환한다.

그 반환된(NULL이 아닌) 상태로 기존 상태 멤버가 전환된다. (state_ = state)

클라이언트에서 인터페이스를 선언하여 상태 패턴을 사용하여 상속된 클래스(상태) 별로 기능을 분리하여 조건문을 대체할 수도 있다.

profile
언리얼 엔진 매니아입니다.

0개의 댓글