Commandパターンとは|GoFデザインパターンの解説

デザインパターンとは IT技術
IT技術

Commandパターンは、GoFのデザインパターンの1つで、リクエストをオブジェクトとしてカプセル化し、異なるリクエストをパラメータ化された方法で実行できるようにします。

この記事では、Commandパターンの概念とその使い方、そしてJavaを使った実装例を紹介します。また、他の言語での利用方法にも触れ、応用の幅を広げる内容となっています。

Commandパターンとは

Commandパターンは、操作をオブジェクトとして表現し、そのオブジェクトをクライアントに渡して実行することで、操作の要求を抽象化します。

このパターンにより、クライアントと受け手が疎結合になり、柔軟な操作の実行が可能になります。

Commandパターンの目的

Commandパターンの目的は、操作をオブジェクトとしてカプセル化し、操作の呼び出し元と実際の処理の実行者を分離することです。

これにより、操作の取り消しや再実行、操作のキューイングなどが簡単に実現できます。

Commandパターンの構成要素

Commandパターンは、以下の主要な要素で構成されます。

Point
  • Command: 操作を定義するインターフェース。
  • ConcreteCommand: Commandインターフェースを実装し、特定の操作を実行。
  • Receiver: 実際に操作を行うオブジェクト。
  • Invoker: Commandオブジェクトを保持し、操作を実行する。
  • Client: InvokerとReceiverに必要なCommandオブジェクトを作成。

Commandパターンの使い方

Commandパターンは、以下のような場面で役立ちます。

操作の取り消しや再実行が必要な場合

Commandパターンを使用することで、実行された操作を記録し、後で取り消したり再実行したりすることが容易になります。

これは、テキストエディタやビデオゲームなどでよく使われるアプローチです。

操作のキューイングや遅延実行

操作をオブジェクトとして扱うため、操作をキューに追加したり、特定の条件が揃ったときに実行するようにすることができます。

たとえば、バッチ処理やマクロ機能の実装に便利です。

シンプルな操作の再利用性向上

同じ操作を複数の場所で再利用したい場合にも、Commandパターンが有効です。操作がオブジェクト化されているため、コードの重複を避けることができます。

Commandパターン実装サンプル

以下に、Javaを使用したCommandパターンの実装サンプルを示します。

このサンプルでは、電気機器を操作するためのリモコンアプリケーションを例にしています。

Commandインターフェース

まず、Commandインターフェースを定義します。

public interface Command {
    void execute();
}
</pre>

<h3>具体的なCommandクラス</h3>
<p>次に、Commandインターフェースを実装する具体的なCommandクラスを作成します。</p>

<pre>
public class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

public class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.off();
    }
}

Receiverクラス

次に、実際に操作を行う受け手(Receiver)クラスです。この例では、ライトが受け手となります。

public class Light {
    public void on() {
        System.out.println("Light is ON");
    }

    public void off() {
        System.out.println("Light is OFF");
    }
}

Invokerクラス

InvokerはCommandを保持し、操作を実行します。以下はリモコンのクラスです。

public class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

Clientクラス

最後に、ClientクラスではInvokerとReceiverを使用して、Commandオブジェクトを作成し、操作を実行します。

public class Client {
    public static void main(String[] args) {
        Light livingRoomLight = new Light();
        Command lightOn = new LightOnCommand(livingRoomLight);
        Command lightOff = new LightOffCommand(livingRoomLight);

        RemoteControl remote = new RemoteControl();

        // ライトをオンにする
        remote.setCommand(lightOn);
        remote.pressButton();

        // ライトをオフにする
        remote.setCommand(lightOff);
        remote.pressButton();
    }
}

この例では、リモコンを使ってライトのオン・オフ操作をCommandパターンで実行しています。

Commandパターンを使用することで、操作の実装を容易に差し替えたり、追加の操作を後から柔軟に追加できる利点があります。

まとめ

Commandパターンは、操作をオブジェクトとしてカプセル化し、操作の実行を柔軟に制御するための非常に強力なデザインパターンです。

操作の取り消しや再実行、キューイング、遅延実行など、さまざまな用途で役立ちます。

このパターンを理解し、適切に実装することで、より柔軟で拡張性のあるアプリケーションを構築することが可能になります。

特にJava、C++、C#のようなオブジェクト指向言語での応用に適しており、多くの場面で活用できるデザインパターンです。

タイトルとURLをコピーしました