步步为营 .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 ,