> For the complete documentation index, see [llms.txt](https://poyos-tech-blog.gitbook.io/poyos-tech-blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://poyos-tech-blog.gitbook.io/poyos-tech-blog/knowledge/design-pattern/command-pattern.md).

# Command Pattern

실행 주체를 지정하기에 좋은 Command 패턴을 코드를 통해 알아보자.

커맨드 패턴은 메서드 호출을 **실제하는 것으로 만든 것이다. ‘메서드 호출을 캡슐화 한 것 ’ 혹은 ‘콜백을 객체지향적으로 표현한 것’ 이라고도 한다.**

구현할 때는 커맨드 역할을 하는 추상 클래스를 만들고 인터페이스로써 상속가능한 동작을 노출한다.

커맨드 패턴은 실행 뿐만 아니라, 되돌리는 동작도 가능해야 한다.

주요 메서드는 execute, undo 2가지가 있고 execute 수행 전 상태를 가지고 있다면 undo 동작에서는 이전 상태를 가지고 execute 에서의 동작을 역으로 수행해주면 된다.

### Player 이동 커맨드 구현 예시 (C#)

```csharp
// 커맨드 추상 클래스 정의
public abstract class Command {
	Actor actor; // 지시할 객체

	// Actor 를 추상화 해놓으면 같은 커맨드 패턴으로 지시할 객체를 지정할 수 있다.
	public Command(Actor actor) {
		actor = actor;
	}

	public abstract void execute();
	public abstract void undo();
}

// 커맨드상속
public class PlayerMoveCommand : Command {
	Vector3 prev;
	Vector3 move;

	public MoveCommand(Actor actor, Vector3 move) {
		base(actor)
		move = move;
	}

	public override void execute() {
 		move(move);
 	}
	
	public override void undo() {
 		move(prev); // 이전 상태로 같은 처리함으로써 undo 동작 성립
	}
	
	private void move(Vector3 v) {
		Player player = this.actor as Player;
		prev = player.transform.position;
 		player.move(v);
	}
}

// 커맨드 획득 예시
public class Player : Actor {
	Command command;
	
	public Command commandByInput(KeyCode key) {
		switch (key) {
			case SPACE:
				return new JumpCommand(this);
			case "A":
				return new PlayerMoveCommand(this, Vector3.Left * this.deltaTime)
			case "D":
				return new PlayerMoveCommand(this, Vector3.Right * this.deltaTime)
			default: 
				return new IdleCommand(this);
		}
	}
}
```
