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

記事内に広告が含まれています。

Commandパターンは、GoF(Gang of Four)によって定義された23のデザインパターンの1つであり、操作のリクエストをオブジェクトとしてカプセル化する方法です。

このパターンにより、命令の発行者(クライアント)と実行者(レシーバー)を分離することができ、柔軟なシステム設計を可能にします。

この記事では、Commandパターンの概要、使用方法、そしてJava、C++、C#、VB.NETでの実装例について詳しく解説します。

Commandパターンとは

Commandパターンは、リクエストをオブジェクトとしてカプセル化し、リクエストを実行するオブジェクトをクライアントから分離するデザインパターンです。

このパターンを使用することで、コマンドの呼び出し、実行、取り消し、再実行を簡単に管理できます。

Commandパターンの利点

Commandパターンの主な利点は、コマンドの呼び出し元と実行者を分離できることです。これにより、以下のような利点が得られます:

  • 操作の履歴管理が容易になる
  • コマンドの取り消しや再実行が容易に行える
  • クライアントとレシーバー間の依存関係を減らすことができる

Commandパターンの使い方

Commandパターンの使用方法は、主に3つの要素で構成されています。

コマンド、レシーバー、そしてインボーカーです。

コマンド

コマンドは、リクエストをカプセル化するオブジェクトで、実行される動作を表現します。

インターフェースで定義され、具体的なコマンドクラスでその実装が行われます。

レシーバー

レシーバーは、実際にリクエストに対して操作を実行するオブジェクトです。

具体的なコマンドクラスがレシーバーに対して操作を行います。

インボーカー

インボーカーは、コマンドを保持し、クライアントからの要求に基づいてコマンドを実行する役割を担います。

インボーカーはコマンドの詳細を知らずに、コマンドを実行できます。

Commandパターン実装サンプル

次に、CommandパターンをJava、C++、C#、VB.NETで実装したサンプルコードを紹介します。

JavaでのCommandパターン実装


interface Command {
    void execute();
}

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

    public void turnOff() {
        System.out.println("The light is off");
    }
}

class LightOnCommand implements Command {
    private Light light;

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

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

class LightOffCommand implements Command {
    private Light light;

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

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

class RemoteControl {
    private Command command;

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

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

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

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();

        remote.setCommand(lightOff);
        remote.pressButton();
    }
}

C++でのCommandパターン実装


#include 
using namespace std;

class Command {
public:
    virtual void execute() = 0;
};

class Light {
public:
    void turnOn() {
        cout << "The light is on" << endl;
    }
    void turnOff() {
        cout << "The light is off" << endl;
    }
};

class LightOnCommand : public Command {
private:
    Light* light;
public:
    LightOnCommand(Light* light) : light(light) {}
    void execute() {
        light->turnOn();
    }
};

class LightOffCommand : public Command {
private:
    Light* light;
public:
    LightOffCommand(Light* light) : light(light) {}
    void execute() {
        light->turnOff();
    }
};

class RemoteControl {
private:
    Command* command;
public:
    void setCommand(Command* command) {
        this->command = command;
    }
    void pressButton() {
        command->execute();
    }
};

int main() {
    Light* light = new Light();
    Command* lightOn = new LightOnCommand(light);
    Command* lightOff = new LightOffCommand(light);

    RemoteControl* remote = new RemoteControl();
    remote->setCommand(lightOn);
    remote->pressButton();

    remote->setCommand(lightOff);
    remote->pressButton();

    delete light;
    delete lightOn;
    delete lightOff;
    delete remote;

    return 0;
}

C#でのCommandパターン実装


using System;

interface Command {
    void Execute();
}

class Light {
    public void TurnOn() {
        Console.WriteLine("The light is on");
    }

    public void TurnOff() {
        Console.WriteLine("The light is off");
    }
}

class LightOnCommand : Command {
    private Light light;

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

    public void Execute() {
        light.TurnOn();
    }
}

class LightOffCommand : Command {
    private Light light;

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

    public void Execute() {
        light.TurnOff();
    }
}

class RemoteControl {
    private Command command;

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

    public void PressButton() {
        command.Execute();
    }
}

class Program {
    static void Main(string[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.SetCommand(lightOn);
        remote.PressButton();

        remote.SetCommand(lightOff);
        remote.PressButton();
    }
}

VB.NETでのCommandパターン実装


Interface Command
    Sub Execute()
End Interface

Class Light
    Public Sub TurnOn()
        Console.WriteLine("The light is on")
    End Sub

    Public Sub TurnOff()
        Console.WriteLine("The light is off")
    End Sub
End Class

Class LightOnCommand
    Implements Command
    Private light As Light

    Public Sub New(light As Light)
        Me.light = light
    End Sub

    Public Sub Execute() Implements Command.Execute
        light.TurnOn()
    End Sub
End Class

Class LightOffCommand
    Implements Command
    Private light As Light

    Public Sub New(light As Light)
        Me.light = light
    End Sub

    Public Sub Execute() Implements Command.Execute
        light.TurnOff()
    End Sub
End Class

Class RemoteControl
    Private command As Command

    Public Sub SetCommand(command As Command)
        Me.command = command
    End Sub

    Public Sub PressButton()
        command.Execute()
    End Sub
End Class

Module Program
    Sub Main()
        Dim light As New Light()
        Dim lightOn As Command = New LightOnCommand(light)
        Dim lightOff As Command = New LightOffCommand(light)

        Dim remote As New RemoteControl()
        remote.SetCommand(lightOn)
        remote.PressButton()

        remote.SetCommand(lightOff)
        remote.PressButton()
    End Sub
End Module

まとめ

Commandパターンは、操作のリクエストをオブジェクトとしてカプセル化し、クライアントとレシーバーを分離する強力なデザインパターンです。

これにより、命令の実行や取り消し、再実行の管理が容易になり、拡張性と柔軟性を高めることができます。

本記事では、Commandパターンの概要とその実装について、Java、C++、C#、VB.NETを使用した具体例を通じて解説しました。

ぜひ、自身のプロジェクトで活用してみてください。

オブジェクト指向プログラミングにおけるGoFの23のデザインパターン
デザインパターンは、ソフトウェア設計の問題を効果的に解決するための再利用可能な解決策です。本記事では、GoF(Gang ...
タイトルとURLをコピーしました