步步为营 .NET 设计模式学习笔记 九、Command(命令模式)
概述
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。这就是本文要说的Command模式。
意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。[GOF 《设计模式》]
结构图
<Design Pattern>Command模式结构图如下:

图1 Command模式结构图
西游记中例子:玉帝传美猴王上天
命令模式不是新的发明,在美猴王大闹天宫之前就有了。那时玉帝命令太白金星召美猴王上天:"金星径入(水帘洞)当中,面南立定道:我是易做图太白金星,奉玉帝招安圣旨,下界请你上大,拜受仙录。"玉帝是系统的客户端,太白金星是命令的发出者,猴王是命令的接收者,圣旨就是命令。玉帝的这一道命令就是要求猴王到上界报到。玉帝只管发出命令,而不管命令是怎样传达到美猴王的。太白金星负责将圣旨传到,可是美猴王怎么执行圣旨、何时执行圣旨是美猴王自己的事。果不然,个久美猴王就大闹了天宫。
这个模拟系统的设计如下:

生活中的例子
Command模式将一个请求封装为一个对象,从而使你可以使用不同的请求对客户进行参数化。用餐时的账单是Command模式的一个例子。服务员接受顾客的点单,把它记在账单上封装。这个点单被排队等待烹饪。注意这里的"账单"是不依赖于菜单的,它可以被不同的顾客使用,因此它可以添入不同的点单项目。

图2 使用用餐例子的Command模式对象图
示例用例结构图:
手机操作系统包括开机、关机、打电话、挂电话、发短信和删除短信功能,其实这就是一个命令模式,类结构示意图如下:

先创建接口ICommand.cs:
public inte易做图ce ICommand
{
/// <summary>
/// 执行命令
/// </summary>
string Execute();
/// <summary>
/// 撤消命令
/// </summary>
string UnExecute();
}
再创建SystemCommand.cs:
public class SystemCommand
{
public string StartUp()
{
return "手机开机";
}
public string ShutDown()
{
return "手机关机";
}
public string SendSMS()
{
return "发短信";
}
public string RemoveSMS()
{
return "删短信";
}
public string CallPhone()
{
return "打电话";
}
public string RingOff()
{
return "挂电话";
}
}
再创建MobileSystem.cs:
public abstract class MobileSystem :ICommand
{
private SystemCommand mobileCommand;
public SystemCommand MobileCommand
{
get
{
return mobileCommand;
}
set
{
mobileCommand = value;
}
}
public MobileSystem(SystemCommand command)
{
this.mobileCommand = command;
}
#region ICommand 成员
public abstract string Execute();
public abstract string UnExecute();
#endregion
}
再创建StartUp.cs:
public class StartUp :MobileSystem
{
#region MobileSystem 成员
public override string Execute()
{
return MobileCommand.StartUp();
}
public override string UnExecute()
{
return MobileCommand.ShutDown();
}
#endregion
public StartUp(SystemCommand command)
: base(command)
{ }
}
再创建Call.cs:
public class Call : MobileSystem
{
#region MobileSystem 成员
public override string Execute()
{
return MobileCommand.CallPhone();
}
public override string UnExecute()
{
return MobileCommand.RingOff();
}
#endregion
public Call(SystemCommand command)
: base(command)
{ }
}
再创建SMS.cs:
public class SMS : MobileSystem
{
#region MobileSystem 成员
public override string Execute()
{
return MobileCommand.SendSMS();
}
public override string UnExecute()
{
return MobileCommand.RemoveSMS();
}
#endregion
public SMS(SystemCommand command)
: base(command)
{ }
}
再创建MobileServer.cs:
public class MobileServer : ICommand
{
private MobileSystem mobileSystem;
public MobileServer(MobileSystem system)
{
this.mobileSystem = system;
}
public string Execute()
{
return mobileSystem.Execute();
}
public string UnExecute()
{
return mobileSystem.UnExecute();
}
}
最后再调用:
public partial class Run : Form
{
public Run()
{
InitializeComponent();
}
private void btnRun_Click(object sender, EventArgs e)
{
SystemCommand command = new SystemCommand();
MobileServer server = new MobileServer(new StartUp(command));
rtbResult.AppendText(server.Execute() + "
");
rtbResult.AppendText(server.UnExecute() + "
");
server = new MobileServer(new Call(command));
rtbResult.AppendText(server.Execute() + "
");
rtbResult.AppendText(server.UnExecute() + "
");
server = new MobileServer(new SMS(command));
rtbResult.AppendText(server.Execute() + "
")补充:Web开发 , ASP.Net ,




