コマンドデザインパターン1

2022年10月13日

コマンド設計パターンの実現テストします

シナリオ

家電リモコンを例にコマンドを割り当てる方法をみていきましょう

クラス図

クライアントコード

namespace P203Command
{
    /// <summary>
    /// Client
    /// ConcreteCommandの作成とそのReceiverの設定の役割を担います
    /// </summary>
    public class ReomoteControlTest
    {
        public static void Main()
        {
            SimpleRomoteControl remote = new SimpleRomoteControl();

            Light light = new Light();
            GarageDoor garageDoor = new GarageDoor();

            LightOnCommand lightOn = new LightOnCommand(light);
            GarageDoorOpenCommand garageDoorOpen = new GarageDoorOpenCommand(garageDoor);

            remote.SetCommand(lightOn);
            remote.ButtonWasPressed();

            remote.SetCommand(garageDoorOpen);
            remote.ButtonWasPressed();
        }
    }
}

説明

Invokerを作成します

SimpleRomoteControl remote = new SimpleRomoteControl();

レシーバーを作成します

Light light = new Light();
GarageDoor garageDoor = new GarageDoor();

ConcreteCommandを作成します

LightOnCommand lightOn = new LightOnCommand(light);
GarageDoorOpenCommand garageDoorOpen = new GarageDoorOpenCommand(garageDoor);

Invokerにコマンドをセットします
実行するためにイベントを発生させます

remote.SetCommand(lightOn);
remote.ButtonWasPressed();

remote.SetCommand(garageDoorOpen);
remote.ButtonWasPressed();

コマンドインターフェイスのコード

using System;
namespace P203Command
{
    /// <summary>
    /// ICommand
    /// 全てのコマンドのためのインターフェースを宣言します
    /// コマンドはExecute()メソッドで起動し、Execute()メソッドは、
    /// レシーバーにアクションを実行するように依頼します
    /// このインターフェースには、Undo()メソッドもあります
    /// </summary>
    public interface ICommand
    {
        void Execute();
        void Undo();
    }
}

説明

全てのコマンドのためのインターフェースを宣言します

ConcreteCommandコード

using System;
namespace P203Command
{
    /// <summary>
    ///  ConcreteCommand
    ///  アクションとReceiverの結びつきを定義します
    ///  InvokerがExecute()メソッドを呼び出してリクエストを行い、
    ///  ConcreteCommandがReceiverの1つ以上の悪所運を呼び出しています
    /// </summary>
    public class LightOnCommand : ICommand
    {
        Light light;

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

        /// <summary>
        /// リクエストの実行に必要なレシーバーのアクションを起動します
        /// </summary>
        public void Execute()
        {
            light.On();
        }

        public void Undo()
        {
            throw new NotImplementedException();
        }
    }
}

説明

アクションとReceiverの結びつきを定義します
リクエストはカプセル化されます

Receiverのコード

namespace P203Command
{
    /// Receiver
    /// リクエストに対処するために必要な処理の実行方法を
    /// 知っています
    /// どのクラスでもReceiverとして動作できます
    public class Light
    {
        internal void On()
        {
            Console.WriteLine("照明を点けました");
        }
    }
}

説明

具体的な動作について記述されています

結果

照明を点けました
ガレージのドアを開けました

参考