Commandパターンとは、アクションをオブジェクトとしてカプセル化し、そのアクションを別のオブジェクトで実行するデザインパターンだ。これにより、操作をキューに入れたり、元に戻したりできる。
たとえば、ゲームで「移動」や「攻撃」などの操作を後でやり直すために履歴として残す場合に、このパターンが使える。
では、サンプルコードを一緒に見ていこう。
例えば、リモコンを使って家電を操作する場面をイメージしてみよう。リモコンのボタンを押すと、テレビをつけたり消したり、音量を上げたりできる。Command パターンでは、その「ボタン押し」を一つの命令として表現し、それを後で実行できる形にするんだ。
まず、リモコンで操作する家電(今回はテレビ)を定義する。テレビには
turnOn() や turnOff() という操作がある。
// テレビを定義する
class TV {
turnOn() {
console.log("テレビをつけました");
}
turnOff() {
console.log("テレビを消しました");
}
}
次に、リモコンのボタンの役割をする 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();
}
}
次に、リモコンを作成する。このリモコンには、コマンドをセットして、そのコマンドを実行するメソッド
pressButton() がある。
// リモコンを定義する
class RemoteControl {
setCommand(command) {
this.command = command;
}
pressButton() {
this.command.execute();
}
}
最後に、テレビとリモコンを使って、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パターンの解説は終わりだ。
このパターンを使うと、操作を後から実行したり、取り消したりすることができるため、複雑な操作の履歴管理や、アクションの再実行に便利だ。