一、概念
①、什么是命令模式?
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
是一种数据驱动的设计模式,它属于行为型模式,请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
②、主要解决什么问题?
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
③、如何解决?
通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
④、何时使用?
在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的,在这种情况下,如何将“行为请求者”与“行为实现者”解耦,将一组行为抽象为对象,可以实现两者之间的松耦合。
⑤、优缺点?
优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
二、图
①、结构图
②、拓展图
三、代码
①、代码类图
②、代码
客户端
class Program
{
static void Main(string[] args)
{ //开店前准备:烤肉厨师,烤肉菜单,服务员
Barbecuer boy = new Barbecuer(); //通过Barbecuer类实例化一个boy对象,即烧烤者
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); // 多态的体现:实例化烤羊肉串对象1
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy); //通过command类,实例化一个烤羊肉串命令2对象,并将值赋予给对象
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); //通过command 类,实例化一个烤翅命令1对象
Waiter girl = new Waiter(); //实例化一个服务员
//开门营业
girl.SetOrder(bakeMuttonCommand1); //设置订单;服务员接收命令
girl.SetOrder(bakeMuttonCommand2); //记录所点菜品
girl.SetOrder(bakeChickenWingCommand1);
girl.Notify(); //服务员一次性通知烤肉厨师执行
Console.Read();
}
}
服务员
public 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();
}
}
}
烧烤者
public class Barbecuer
{
public void BakeMutton() //创建烤羊肉的方法
{
Console.WriteLine("烤羊肉串!");
}
public void BakeChickenWing() //实现烤鸡翅的方法
{
Console.WriteLine("烤鸡翅!");
}
}
抽象命令类
public abstract class Command
{
protected Barbecuer receiver; //引用烧烤者,因为命令是给烧烤者的
public Command(Barbecuer receiver)
{
this.receiver = receiver; //命令构造函数,所传参数为烧烤者
}
public abstract 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(); //接受者实现烤鸡翅行为
}
}
四、拓展
http://www.cnblogs.com/wolf-sun/p/3618911.html?utm_source=tuicool(更深入的理解)