# 커맨드 패턴

커맨드 패턴은 요청을 캡슐화하며, 클라이언트의 다양한 요청을 큐에 넣거나 기록하며, 실행 취소같은 작업을 수행할 수도 있다.

이 패턴은 작업을 호출하는 클라이언트와 작업을 실제로 수행하는 부분을 분리하여 둘 사이의 유연성을 높이고 분리를 가능하게 한다.

유즈케이스 중 하나는 실행 취소 기능을 구현하려는 경우이다. 다음 예제를 보자.

```
class Command {
  execute() {
    throw new Error('execute가 구현되어야 합니다.');
  }

  undo() {
    throw new Error('undo가 구현되어야 합니다.');
  }
}

class AddCommand extends Command {
  constructor(receiver, value) {
    super();
    this.receiver = receiver;
    this.value = value;
  }

  execute() {
    this.receiver.add(this.value);
  }

  undo() {
    this.receiver.remove(this.value);
  }
}

class RemoveCommand extends Command {
  constructor(receiver: Receiver, value) {
    super();
    this.receiver = receiver;
    this.value = value;
  }

  execute() {
    this.receiver.remove(this.value);
  }

  undo() {
    this.receiver.add(this.value);
  }
}

class Receiver {
  constructor() {
    this.items = [];
  }

  add(item) {
    this.items.push(item);
    console.log(`item 추가 ${item}`);
  }

  remove(item) {
    const index = this.items.indexOf(item);
    if (index !== -1) {
      this.items.splice(index, 1);
      console.log(`item 삭제 ${item}`);
    }
  }
}

class Invoker {
  constructor() {
    this.commands = [];
  }

  execute(command) {
    command.execute();
    this.commands.push(command);
  }

  undo() {
    const command = this.commands.pop();
    if (command) {
      command.undo();
    }
  }
}

const receiver = new Receiver();
const addCommand = new AddCommand(receiver, 'foo');
const removeCommand = new RemoveCommand(receiver, 'bar');

const invoker = new Invoker();
invoker.execute(addCommand);
invoker.execute(removeCommand);
invoker.undo();

```

For the site tree, see the [root Markdown](https://slashpage.com/develop.md).
