封裝命令執行、撤銷、重做邏輯,維護命令歷史:
using System;
using System.Collections.Generic;
using System.Text;
namespace Pattern.Command
{
///
/// 請求者(Invoker)角色
///
public class Message
{
///
/// 命令集合(保存每次操作)
///
private List<ICommand> _listCommand = new List<ICommand>();
///
/// 命令集合中當前要執行的命令的索引
///
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;
}
}
}
_listCommand 記錄所有執行過的命令。current 指向下一個要執行/重做的命令位置。Do() 建立命令 → Execute() → 加入歷史 → 指標前進。Undo() 指標後退 → 取得命令 → UnExecute()(反向操作)。Redo() 取得當前命令 → UnExecute() → 指標前進。// 原始碼中 Redo 呼叫 UnExecute(),通常應呼叫 Execute() 重新執行
ICommand cmd = _listCommand[current++];
rtn += cmd.UnExecute() + " "; // 疑似應為 cmd.Execute()
標準命令模式中 Redo 應重新執行命令(Execute()),而非執行反向操作。此處可能為示例簡化或邏輯差異。
| 模式角色 | 本例類別 | 說明 |
|---|---|---|
| Command | ICommand | 命令介面 |
| ConcreteCommand | SqlMessageCommand | 具體命令,封裝 Receiver 與 Action |
| Receiver | SqlMessage | 接收者,執行實際操作 |
| Invoker | Message | 請求者,管理命令歷史與撤銷重做 |