명령 패턴 - 간단하게 정리하자면 함수 호출을 매개변수화 한 것?

콜백 함수, 함수 포인터를 사용하여 구현할 수 있다.

 

2.1 입력키 변경

 

버튼을 눌렀을때 특정 메서드(행동)가 수행하도록 하는 코드가 있다면

 

1. 모든 행동을 실행하는 공통 상위 클래스 Command를 정의 (execute 함수가 있는 인터페이스)

2. 행동별로 상위 클래스를 상속받는 하위 클래스를 만들고 execute 함수를 정의 (execute에서 실제로 메서드를 호출)

3. 입력 핸들러 코드에는 버튼마다 상위 클래스 포인터를 저장

4. 입력 핸들러 초기화 시점에 버튼에 하위 클래스 객체를 바인드함

 

2.2 액터에게 지시하기

위의 예에서 execute 함수에 매개변수로 GameActor 객체를 받는다.

 

명령을 실행할 때 액터만 바꾸면 플레이어가 아닌 액터에 명령을 실행 할 수 있다.

플레이어와 같은 명령을 사용하는 AI 캐릭터가 있다면 적용할 수 있다.

 

Command 객체를 선택하는 부분 (입력 핸들러 코드)과 액터(누가 명령을 수행하는지)를 디커플링함으로써 코드가 유연해진다.

 

2.3 실행취소와 재실행

Command 클래스에 가상 함수 Undo()를 정의한다.

 

어떤 일을 하는지를 정의한 명령 객체(Command를 상속받은)를 반복해서 생성한다.

그 명령 객체는 이전 명령의 상태를 저장할 수 있어야 한다. (execute() 함수에서 현재 상태를 이전 상태에 기록하고 상태를 변경해야 한다.)

 

Undo() 함수는 현재 상태를 이전 상태로 바꿔야한다.

 

이전 명령의 상태를 저장하고 있어야 하므로 Command 자료형을 저장할 수 있는 배열이나 스택같은 곳에 명령 객체를 동적으로 생성해 저장하고 있어야 한다. (버튼 등의 입력으로 명령을 수행할 때 마다)

 

이전 상태로 돌아가기 위해서는 배열이나 스택의 포인터를 이동해가면서 포인터가 가리키는 곳의 명령 객체의 Undo() 함수를 호출하면 된다. 

 

재실행은 게임에서 잘 쓰이지 않을 수도 있지만, '리플레이'는 게임에서 자주 쓰인다.

매프레임마다 전체 게임 상태를 저장하는 대신 전체 개체가 실행하는 명령 모두를 매 프레임 저장한 뒤 리플레이 할때 저장한 명령들을 순서대로 실행해 게임을 시뮬레이션한다.

 

+ Recent posts