命令模式
将一个请求封装为对象,从而使你可用不同请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作
abstractclass Command
{
protected Receiver re;
public Command(Receiver re)
{
this.re = re;
}
abstract public void Execute();
};
//具体的命令,将一个接收者对象绑定到一个动作,调用接收者相应操作,实现execute
class ConcretCommand :Command
{
public ConcretCommand(Receiver re) :base(re)
{
}
public override void Execute()
{
re.Action();
}
};
//Invode类,要求该命令执行这个请求
class Invoke
{
private Command comm;
public void SetCommand(Command comm)
{
this.comm = comm;
}
public void ExecuteCommand()
{
command.Execute();
}
};
//知道如何实施执行与一个请求相关操作
class Receiver
{
public void Action()
{
Console.WriteLine("执行请求!");
}
};
//客户端
void main()
{
//做准备
Receiver r = new Receiver();
Command c = new ConcretCommand(r);
Invoke i = new Invoke();
//客户发出请求
i.SetCommand(c);
i.ExecuteCommand();
}
优点:
1、较容易设计命令队列
2、若需要,较容易将命令记入日志
3、允许接收请求者决定是否接收
4、易实现对请求的撤销和重做
5、易于新增命令类
最重要的是命令模式将请求操作的对象和执行操作的对象分割开了
这里举了一个客户去烧烤店吃烧烤的例子。
分别有客户,服务员,厨房师傅,结构如下:
abstractclass Command
{
protected Barbecuer re;
public Command(Barbecuer re) //确定后台厨房谁来烧烤
{
this.re = re;
}
abstract public void ExecuteCommand();
};
class BakeMuttonCommand :Command
{
public BakeMuttonCommand(Barbecuer b) :base(b)
{}
public void ExecuteCommand()
{
b.BakeMutton();
}
};
class BakePigCommand :Command
{
public BakePigCommand(Barbecuer b) :base(b)
{}
public void ExecuteCommand()
{
b.Pig();
}
};
public class Waiter
{
private IList<Command> orders = newIList<Commond>();
//设置订单
public void SetOrder(Command comm)
{
if (comm.ToString() =="BakePigCommand") //假设我们这里没猪肉了,客户如果点了就要告知其没了
Console.WriteLine("没猪肉了");
else
{
orders.Add(comm);
}
}
//取消订单
public void CancelOrder(Command comm)
{
orders.Remove(comm);
}
//通知全部执行
public void Notify()
{
foreach(Command var in orders)
{
var.ExecuteCommand();
}
}
};
//客户端
void main()
{
//准备
Barbecuer oldman = new Barbecuer();
Command bmc1 = new BakeMuttonCommand(oldman);
Command bmc2 = new BakeMuttonCommand(oldman);
Command bpc1 = new BakePigCommand(oldman);
Waiter w = new Waiter();
//开始营业
w.SetOrder(bmc1);
w.SetOrder(bmc2);
w.SetOrder(bpc1);
w.Notify();
}