1.1 定義と概念

コマンドパターンは、リクエストをオブジェクトとしてカプセル化し、クライアントに異なるリクエストをパラメーターとして渡すことができるようにする行動設計パターンです。

1.2 コマンドパターンの目的

コマンドパターンの主な目的は、送信者と受信者を切り離すことです。リクエストをオブジェクトにカプセル化することで、送信者はコマンドオブジェクトと直接やり取りすることなく、受信者とやり取りすることができます。

2. コマンドパターンの特性と利点

コマンドパターンの特性と利点は以下の通りです:

  • リクエストをオブジェクトにカプセル化することで、送信者と受信者を切り離す。
  • リクエストをキューに入れたり、ログを記録したり、元に戻す操作を行ったりできる。
  • 元のコードを変更せずに新しいコマンドを拡張することができる。

3. コマンドパターンの実際の応用例

コマンドパターンは、以下のようなシナリオで利用されます:

  • オブジェクトからリクエストを切り離す必要がある場合。
  • 元に戻す操作ややり直しをサポートする場合。
  • キューに沿って一連の操作を実行する場合。

4.1 UMLクラス図

Golangコマンドパターン

4.2 例の紹介

この例では、コマンドパターンの簡単な実装を作成します。受信者としてTVがあり、オンおよびオフのアクションを実行できます。また、特定のコマンドを設定して実行できる呼び出し者としてリモコンがあります。

4.3.1 コマンドインターフェースの定義

type ICommand interface {
    Execute()
}

4.3.2 具体的なコマンドクラスの実装

type ConcreteCommand struct {
    receiver IReceiver
}

func (c *ConcreteCommand) Execute() {
    c.receiver.Action()
}

4.3.3 受信者インターフェースの定義

type IReceiver interface {
    Action()
}

4.3.4 具体的な受信者クラスの実装

type Receiver struct {}

func (r *Receiver) Action() {
    fmt.Println("操作を実行中")
}

4.3.5 呼び出し者の役割の実装

type Invoker struct {
    command ICommand
}

func (i *Invoker) SetCommand(command ICommand) {
    i.command = command
}

func (i *Invoker) ExecuteCommand() {
    i.command.Execute()
}

4.3.6 クライアントコードの例

func main() {
    receiver := &Receiver{}
    command := &ConcreteCommand{receiver: receiver}
    invoker := &Invoker{}
    invoker.SetCommand(command)
    invoker.ExecuteCommand()
}

5. コマンドパターンとストラテジーパターンの違い

コマンドパターンとストラテジーパターンは、ある程度似ています。ともに特定の動作をオブジェクトにカプセル化する点です。違いは、コマンドパターンは主にリクエストをオブジェクトとしてカプセル化し、元に戻すおよび実行キューなどの機能を実装するのに対し、ストラテジーパターンは主に一連のアルゴリズムをカプセル化して、実行時にアルゴリズムを動的に選択することに向いています。

コマンドパターンはログ記録や会計などの操作に適しており、一方、ストラテジーパターンはビジネスロジックの柔軟な変更に適しています。