커맨드 패턴

윤영기·2022년 11월 17일
0

TIL

목록 보기
10/11
post-thumbnail

Command Pattern

소프트웨어 마에스트로 스터디 중 커맨드 패턴에 대한 자료입니다.

커맨드 패턴에 대하여 알아봅시다

간단한 게임을 하나 제작할 예정입니다.
이번 게임에서는 두가지 버튼만 활용할 예정이고, 버튼들은 altctrl 만 사용할 예정이기에, alt에는 jump ctrl 에는 attack 이라는 함수를 매핑을 했습니다.

사실 이정도의 게임이라면 문제가 없습니다. 하지만 키보드 세팅이 복잡한 게임이라면 어떻게 될까요?
그럼 키 마다 세팅을 할 것입니다. 그리고 모든 키 매핑이 character에 관한 것도 아니고, esc는 게임 세팅창을 여는 등 다양한 action이 이루어 질 것입니다.

여기서 더 복잡한 상황을 생각해 보겠습니다.

위의 영상을 보면, 같은 공격키를 누르지만, 공격에는 곰 -> 새 -> 호랑이 -> 창 순서로 공격하게 되어 있습니다.

그걸 간단하게 코드로 보면 다음과 같이, ctrl을 눌렀을 때, 상황에 따라 다른 공격이 이루어지도록 수정을 해둬야 됩니다.

단순히 키를 누른다 -> 해당 키에 해당하는 Action을 취한다 면 됐다고 생각했던 코드가 점점 복잡해져 가는게 보이시나요?

하지만 여기서 끝이 나지 않습니다. 보통 게임에는 유저가 원하는 키에 유저가 원하는 Action을 취하도록 커스텀 가능한 환경을 제공합니다. 그럼 alt에 해당했던 jumpnpc/채집으로 바뀌어야 됩니다.
이런 수정사항이 게임에 runtime에 수정되기란 상당히 힘들어 보입니다.

아니면 게임을 진행 할 수록 아까 보았던 attack 순서가 바뀌거나 추가가 되었다면 어떻게 될까요? 공격으로 지정된 키를 찾아 공격에 대한 로직을 수정해야 될 것입니다.

Command Pattern을 활용하면 다음과 같이 간결하고 유지보수가 쉬운 형태로 유지 할 수 있습니다.

Command Pattern에는 5개의 등장인물이 존재합니다.

  1. Command : 명령의 Interface를 정의
  2. Concrete Command : Command Interface를 구현
  3. Invoker : 명령의 행동을 개시하는 역할로 Command를 호출
  4. Receiver : Command가 실행될 때 대상이 되는 역할
  5. Client : Concrete Command를 생성 및 Receiver 역할을 할당

Command는 단순히 실행을 하라는 execute 메소드만 생성을 하고, Concrete Command에서 해당하는 execute 메소드를 구현을 합니다.

예를 들어, AttackCommand에서의 execute라는 명령은 캐릭터를 공격을 유발합니다.

이와 유사하게 JumpCommand도 만들 수 있습니다.

마찬가지로, SettingCommand는 game에 해당하는 setting창을 여는 Concrete Command또한 만들 수 있습니다.

해당 command는 멤버변수는 character가 아닌 game임에 주의!

이제 Receiver는 Concrete Command의 실행에서 사용되는 클래스이다. 여기서 게임에서 동작하는 실제 로직을 작성하면 됩니다.

Client는 버튼으로, 해당 버튼이 어떠한 커맨드를 할 지 지정할 수 있는 setCommand 메소드가 존재하며, Invoke된 경우 커맨드를 실행시킬 수 있는 onPressed란 메소드를 구현해 주었습니다.

이제 실제로 Main에서 동작시켜보면 다음과 같습니다.

우선, 필요한 버튼, 커맨드, Receiver 등을 할당시켜줍니다.
그 다음, 필요한 버튼에 원하는 커맨드를 setCommand로 할당시켜 줍니다.
마지막으로, 어떠한 입력이 나왔을 때, 원하는 버튼에 해당하는 command만 실행시켜주면 끝입니다.

괜히 더 복잡해 보일 수 있지만, 유지보수의 관점에서 보면 정말 좋습니다.
아까와 같은 상황처럼, 버튼에 해당하는 Action이 수정되어야 한다면, Button.setCommand(원하는 커맨드) 한줄로 수정할 수 있게 됩니다.

혹은 공격에 대한 로직에 수정이 필요하다면, character 안에서 attack의 로직만 수정해 주면 되기에, 유지보수가 정말 쉬워집니다.

이걸 sequence diagram에서 보면 다음과 같습니다.

  1. 미리 버튼에 Command를 설정해
  2. 버튼을 누른다면
  3. 해당하는 Command의 execute를 호출
  4. execute에 해당하는 행동을 Receiver가 동작

팀원이 Unity로 만든 Command Pattern 으로 구현한 간단한 게임

https://github.com/IamGroooooot/red-slime

0개의 댓글