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