天天看點

樂在其中設計模式(C#) - 指令模式(Command Pattern)

樂在其中設計模式(C#) - 指令模式(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; 

                /// Message内容 

                public string Message 

                        get { return _message; } 

                        set { _message = value; } 

                private DateTime _publishTime; 

                /// Message釋出時間 

                public DateTime PublishTime 

                        get { return _publishTime; } 

                        set { _publishTime = value; } 

        } 

}

Action

        /// enum 

        /// 定義操作的兩種方法Insert和Delete 

        public enum Action 

                /// Insert 

                Insert, 

                /// Delete 

                Delete 

SqlMessage

        /// 接收者(Receiver)角色 

        /// Sql方式操作Message 

        public class SqlMessage 

                /// 操作 

                /// <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); 

                        } 

                /// 插入Message 

                private void Insert(MessageModel mm) 

                        // 代碼略 

                /// 删除Message 

                private void Delete(MessageModel mm) 

ICommand

        /// 指令(Command)角色 

        public interface ICommand 

                /// 執行 

                /// <returns>操作的方法及操作的資訊</returns> 

                string Execute(); 

                /// 取消執行 

                string UnExecute(); 

SqlMessageCommand

        /// 具體指令(ConcreteCommand)角色 

        public class SqlMessageCommand : ICommand 

                /// 操作的方法 

                private Action _action; 

                /// Message實體對象 

                private MessageModel _mm; 

                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); 

                /// 獲得取消執行的算法 

                /// <returns></returns> 

                private Action GetUndoAction(Action action) 

                        Action undo; 

                                        undo = Action.Delete;    

                                        undo = Action.Insert; 

                                // 這句沒啥用 

                                default : 

                        return undo; 

Message

        /// 請求者(Invoker)角色 

        public class Message 

                /// 指令集合(儲存每次操作) 

                private List<ICommand> _listCommand = new List<ICommand>(); 

                /// 指令集合中目前要執行的指令的索引 

                private int current = 0; 

                /// 執行Sql 

                public string Do(Action action, MessageModel mm) 

                        string rtn = ""; 

                        ICommand cmd = new SqlMessageCommand(action, mm); 

                        rtn = cmd.Execute(); 

                        _listCommand.Add(cmd); 

                        current++; 

                        return rtn; 

                /// 撤銷 

                /// <param name="levels">執行撤銷操作的次數</param> 

                /// <returns>操作的方法及操作的資訊(用空格分開多條記錄)</returns> 

                public string Undo(int levels) 

                        for (int i = 0; i < levels; i++) 

                                if (current > 0) 

                                { 

                                        ICommand cmd = _listCommand[--current]; 

                                        rtn += cmd.UnExecute() + " "; 

                                } 

                /// 重複 

                /// <param name="levels">執行重複操作的次數</param> 

                public string Redo(int levels) 

                                if (current < _listCommand.Count - 1) 

                                        ICommand cmd = _listCommand[current++]; 

client

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(m.Do(Action.Insert, new MessageModel("第2條", DateTime.Now))); 

                Response.Write(m.Do(Action.Insert, new MessageModel("第3條", DateTime.Now))); 

                Response.Write(m.Do(Action.Insert, new MessageModel("第4條", DateTime.Now))); 

                Response.Write(m.Do(Action.Delete, new MessageModel("第2條", DateTime.Now))); 

                Response.Write(m.Do(Action.Insert, new MessageModel("第5條", DateTime.Now))); 

                Response.Write(m.Do(Action.Delete, new MessageModel("第3條", DateTime.Now))); 

                Response.Write(m.Do(Action.Insert, new MessageModel("第6條", DateTime.Now))); 

                Response.Write(m.Do(Action.Insert, new MessageModel("第7條", DateTime.Now))); 

                Response.Write("撤銷4次操作"); 

                Response.Write(m.Undo(4)); 

                Response.Write("重複2次操作"); 

                Response.Write(m.Redo(2)); 

                Response.Write("撤銷3次操作"); 

                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條 

參考

<a href="http://www.dofactory.com/Patterns/PatternCommand.aspx" target="_blank">http://www.dofactory.com/Patterns/PatternCommand.aspx</a>

OK

<a href="http://down.51cto.com/data/100859" target="_blank">[源碼下載下傳]</a>

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/344545,如需轉載請自行聯系原作者