Commandパターンの解説

Commandパターンとは、アクションをオブジェクトとしてカプセル化し、そのアクションを別のオブジェクトで実行するデザインパターンだ。これにより、操作をキューに入れたり、元に戻したりできる。

たとえば、ゲームで「移動」や「攻撃」などの操作を後でやり直すために履歴として残す場合に、このパターンが使える。

では、サンプルコードを一緒に見ていこう。

解説

例えば、リモコンを使って家電を操作する場面をイメージしてみよう。リモコンのボタンを押すと、テレビをつけたり消したり、音量を上げたりできる。Command パターンでは、その「ボタン押し」を一つの命令として表現し、それを後で実行できる形にするんだ。

Step 1: 家電(テレビ)を定義する

まず、リモコンで操作する家電(今回はテレビ)を定義する。テレビには turnOn()turnOff() という操作がある。


// テレビを定義する
class TV {
  turnOn() {
    console.log("テレビをつけました");
  }

  turnOff() {
    console.log("テレビを消しました");
  }
}
      

Step 2: Command を定義する

次に、リモコンのボタンの役割をする Command を定義する。ボタンには、「テレビをつける」と「テレビを消す」命令を作ってみよう。


// Command インターフェースを定義する
class Command {
  execute() {
    throw new Error("executeメソッドはサブクラスで実装してください");
  }
}

// テレビをつけるコマンド
class TurnOnCommand extends Command {
  constructor(tv) {
    super();
    this.tv = tv;
  }

  execute() {
    this.tv.turnOn();
  }
}

// テレビを消すコマンド
class TurnOffCommand extends Command {
  constructor(tv) {
    super();
    this.tv = tv;
  }

  execute() {
    this.tv.turnOff();
  }
}
      

Step 3: リモコンを定義する

次に、リモコンを作成する。このリモコンには、コマンドをセットして、そのコマンドを実行するメソッド pressButton() がある。


// リモコンを定義する
class RemoteControl {
  setCommand(command) {
    this.command = command;
  }

  pressButton() {
    this.command.execute();
  }
}
      

Step 4: Command パターンを使って操作する

最後に、テレビとリモコンを使って、Command パターンを実行してみよう。リモコンのボタンを押して、テレビをつけたり消したりする。


// テレビとリモコンを作成
const tv = new TV();
const remoteControl = new RemoteControl();

// テレビをつけるコマンドをセットして実行
const turnOnCommand = new TurnOnCommand(tv);
remoteControl.setCommand(turnOnCommand);
remoteControl.pressButton(); // 結果: テレビをつけました

// テレビを消すコマンドをセットして実行
const turnOffCommand = new TurnOffCommand(tv);
remoteControl.setCommand(turnOffCommand);
remoteControl.pressButton(); // 結果: テレビを消しました
      

Commandパターンの重要なポイント

これでCommandパターンの解説は終わりだ。
このパターンを使うと、操作を後から実行したり、取り消したりすることができるため、複雑な操作の履歴管理や、アクションの再実行に便利だ。