コマンドモード(コマンド)定義:要求をオブジェクトとしてカプセル化し、要求を発行する責任と要求を実行する責任を分離します。このように、2つはコマンドオブジェクトを介して通信するため、コマンドオブジェクトの保存、転送、呼び出し、追加、および管理に便利です。
たとえば、レストランに行って食事をする場合、メニューはゲストが到着するまでカスタマイズされませんが、事前に構成されています。このように、ゲストは一時的な注文を許可するのではなく、来たときに料理を注文するだけで済みます。レストランが提供するメニューは、コマンドモードの実施形態であるリクエストと処理を分離することと同等です。
シナリオの使用:
- メソッドのリクエスターとメソッドの実装者の間に密接な結合関係がある場合
利点:
- ミドルウェア(抽象インターフェース)を導入することにより、システムの結合度を減らします。
- 拡張性は良好で、コマンドの追加や削除は非常に便利です。コマンドモードを使用してコマンドを追加および削除しても、他のカテゴリには影響せず、「開閉の原則」を満たします。
- マクロコマンドを実現できます。コマンドモードを結合モードと組み合わせて、複数のコマンドを結合コマンド、つまりマクロコマンドにアセンブルすることができます。
- 元に戻す操作とやり直し操作を実現するのに便利です。コマンドモードと後述のメモモードを組み合わせることで、コマンドのキャンセルや復元を実現できます。
- 既存のコマンドに基づいて、追加の機能を追加できます。たとえば、デコレータモードと組み合わせたロギングはより柔軟になります。
短所:
- 多数の特定のコマンドクラスが生成される場合があります。特定の操作ごとに特定のコマンドクラスを設計する必要があるため、これによりシステムが複雑になります。
- コマンドモードの結果は、実際にはレシーバーの実行結果ですが、コマンドの形式でリクエストと実装を構造化、分離するために、追加のタイプ構造が導入されています(リクエスターと抽象コマンドインターフェイスが導入されています) 、これは理解の難しさを増します。しかし、これはデザインパターンの一般的な問題でもあります。抽象化すると必然的にクラスの数が増えます。コードの抽出は、コードの集約よりも確実に理解するのが困難です。
コードの背景:バーベキューに行くとき、ウェイターに一度に注文するのは顧客であることが多く、レコードが完成した後、ウェイターはシェフに注文し、ウェイターは分割の役割を果たしますリクエストとそれを実行します。
コマンドクラス:
//抽象命令
abstract class Command
{
protected Barbecuer receiver;
public Command (Barbecuer receiver)//只需要确定烤肉串的人是谁
{
this.receiver = receiver;
}
//执行命令
abstract public void ExcuteCommand();
}
//烤羊肉串命令
class BakeMuttonCommand : Command
{
public BakeMuttonCommand(Barbecuer receiver):base(receiver)
{
}
public override void ExcuteCommand()//具体命令类,执行命令时,执行具体的行为
{
receiver.BakeMutton();
}
}
//烤鸡翅命令
class BakeChickenWingCommand:Command
{
public BakeChickenWingCommand(Barbecuer receiver):base(receiver)
{
}
public override void ExcuteCommand()
{
receiver.BakeChickenWing();
}
}
ウェイターカテゴリー:
class Waiter
{
//增加存放具体命令的容器
private IList<Command> orders = new List<Command>();
//设置订单
public void SetOrder(Command command)
{
if (command.ToString() == "命令模式__经营烧烤摊.BakeChickenWingCommand")
{
Console.WriteLine("服务员:鸡翅没有了,点点别的吧,我们家还有烤腰子");
}
else
{
orders.Add(command);
Console.WriteLine("增加订单:"+command.ToString()+" 时间:"+DateTime.Now.ToString());
}
}
//取消订单
public void CancelOrder(Command command )
{
orders.Remove(command);
Console.WriteLine("取消订单:" + command.ToString() + " 时间:" + DateTime.Now.ToString());
}
//通知全部执行
public void Notify()
{
foreach(Command cmd in orders)
{
cmd.ExcuteCommand();
}
}
}
シェフカテゴリー:
class Barbecuer
{
//烤羊肉串
public void BakeMutton()
{
Console.WriteLine("烤羊肉串!");
}
//烤鸡翅
public void BakeChickenWing()
{
Console.WriteLine("烤鸡翅!");
}
}
クライアント:
static void Main(string[] args)
{
//开店前的准备
Barbecuer boy = new Barbecuer();//烤串的人是boy
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);//烤羊肉串命令
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);//烤羊肉串命令
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);//烤鸡翅命令
Waiter girl = new Waiter();//服务员是girl
//开门营业
girl.SetOrder(bakeMuttonCommand1);//把烤羊肉串放入订单
//执行通知
girl.SetOrder(bakeMuttonCommand2 );
girl.SetOrder(bakeChickenWingCommand1 );
girl.Notify();//下单完毕一起通知
Console.Read();
}