二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern)
介绍
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
示例
有一个Message实体类,某个类对它的操作有Insert()和Delete()方法。现在要求可以对之前的所有操作做撤销和重复。
MessageModel
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// Message实体类 /// </summary> public class MessageModel { /// <summary> /// 构造函数 /// </summary> /// <param name="msg">Message内容</param> /// <param name="pt">Message发布时间</param> public MessageModel(string msg, DateTime pt) { this._message = msg; this._publishTime = pt; } private string _message; /// <summary> /// Message内容 /// </summary> public string Message { get { return _message; } set { _message = value; } } private DateTime _publishTime; /// <summary> /// Message发布时间 /// </summary> public DateTime PublishTime { get { return _publishTime; } set { _publishTime = value; } } } }
Action
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// enum /// 定义操作的两种方法Insert和Delete /// </summary> public enum Action { /// <summary> /// Insert /// </summary> Insert, /// <summary> /// Delete /// </summary> Delete } }
SqlMessage
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// 接收者(Receiver)角色 /// Sql方式操作Message /// </summary> public class SqlMessage { /// <summary> /// 操作 /// </summary> /// <param name="action">操作的方法</param> /// <param name="mm">Message实体对象</param> public void Operation(Action action, MessageModel mm) { switch (action) { case Action.Insert : Insert(mm); break; case Action.Delete : Delete(mm); break; } } /// <summary> /// 插入Message /// </summary> /// <param name="mm">Message实体对象</param> private void Insert(MessageModel mm) { // 代码略 } /// <summary> /// 删除Message /// </summary> /// <param name="mm">Message实体对象</param> private void Delete(MessageModel mm) { // 代码略 } } }
ICommand
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// 命令(Command)角色 /// </summary> public interface ICommand { /// <summary> /// 执行 /// </summary> /// <returns>操作的方法及操作的信息</returns> string Execute(); /// <summary> /// 取消执行 /// </summary> /// <returns>操作的方法及操作的信息</returns> string UnExecute(); } }
SqlMessageCommand
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// 具体命令(ConcreteCommand)角色 /// </summary> public class SqlMessageCommand : ICommand { /// <summary> /// 操作的方法 /// </summary> private Action _action; /// <summary> /// Message实体对象 /// </summary> private MessageModel _mm; /// <summary> /// 构造函数 /// </summary> /// <param name="action">操作的方法</param> /// <param name="mm">Message实体对象</param> public SqlMessageCommand(Action action, MessageModel mm) { this._action = action; this._mm = mm; } /// <summary> /// 执行 /// </summary> /// <returns>操作的方法及操作的信息</returns> public string Execute() { new SqlMessage().Operation(_action, _mm); return _action.ToString() + ":" + _mm.Message; } /// <summary> /// 取消执行(调用一个方法,以决定取消执行的算法) /// </summary> /// <returns>操作的方法及操作的信息</returns> public string UnExecute() { _action = GetUndoAction(_action); new SqlMessage().Operation(_action, _mm); return _action.ToString() + ":" + _mm.Message; } /// <summary> /// 获得取消执行的算法 /// </summary> /// <param name="action">操作的方法</param> /// <returns></returns> private Action GetUndoAction(Action action) { Action undo; switch (action) { case Action.Insert : undo = Action.Delete; break; case Action.Delete : undo = Action.Insert; break; // 这句没啥用 default : undo = Action.Insert; break; } return undo; } } }
Message
using System; using System.Collections.Generic; using System.Text; namespace Pattern.Command { /// <summary> /// 请求者(Invoker)角色 /// </summary> public class Message { /// <summary> /// 命令集合(保存每次操作) /// </summary> private List<ICommand> _listCommand = new List<ICommand>(); /// <summary> /// 命令集合中当前要执行的命令的索引 /// </summary> private int current = 0; /// <summary> /// 执行Sql /// </summary> /// <param name="action">操作的方法</param> /// <param name="mm">Message实体对象</param> /// <returns>操作的方法及操作的信息</returns> public string Do(Action action, MessageModel mm) { string rtn = ""; ICommand cmd = new SqlMessageCommand(action, mm); rtn = cmd.Execute(); _listCommand.Add(cmd); current++; return rtn; } /// <summary> /// 撤销 /// </summary> /// <param name="levels">执行撤销操作的次数</param> /// <returns>操作的方法及操作的信息(用空格分开多条记录)</returns> public string Undo(int levels) { string rtn = ""; for (int i = 0; i < levels; i++) { if (current > 0) { ICommand cmd = _listCommand[--current]; rtn += cmd.UnExecute() + " "; } } return rtn; } /// <summary> /// 重复 /// </summary> /// <param name="levels">执行重复操作的次数</param> /// <returns>操作的方法及操作的信息(用空格分开多条记录)</returns> public string Redo(int levels) { string rtn = ""; for (int i = 0; i < levels; i++) { if (current < _listCommand.Count - 1) { ICommand cmd = _listCommand[current++]; rtn += cmd.UnExecute() + " "; } } return rtn; } } }
Client
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using Pattern.Command; public partial class Command : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Message m = new Message(); Response.Write("操作"); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第1条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第2条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第3条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第4条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Delete, new MessageModel("第2条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第5条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Delete, new MessageModel("第3条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第6条", DateTime.Now))); Response.Write("<br />"); Response.Write(m.Do(Action.Insert, new MessageModel("第7条", DateTime.Now))); Response.Write("<br />"); Response.Write("<br />"); Response.Write("撤销4次操作"); Response.Write("<br />"); Response.Write(m.Undo(4)); Response.Write("<br />"); Response.Write("<br />"); Response.Write("重复2次操作"); Response.Write("<br />"); Response.Write(m.Redo(2)); Response.Write("<br />"); Response.Write("<br />"); Response.Write("撤销3次操作"); Response.Write("<br />"); Response.Write(m.Undo(3)); } }
运行结果
操作
Insert:第1条
Insert:第2条
Insert:第3条
Insert:第4条
Delete:第2条
Insert:第5条
Delete:第3条
Insert:第6条
Insert:第7条
撤销4次操作
Delete:第7条 Delete:第6条 Insert:第3条 Delete:第5条
重复2次操作
Insert:第5条 Delete:第3条
撤销3次操作
Insert:第3条 Delete:第5条 Insert:第2条