命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
下面举例说明:
首先定义命令的具体执行者
/// <summary> /// 命令接受者,有具体的执行发法 /// </summary> public class Receiver { public void WriteError(string errorMsg) { Console.WriteLine("Error: {0}",errorMsg); } public void WriteInfo(string infoMsg) { Console.WriteLine("Info: {0}",infoMsg); } }
定义抽象命令和多个具体的命令:
/// <summary> ///命令抽象类,需要一个命令的执行者 /// </summary> public abstract class Command { protected Receiver receiver; public Command(Receiver writer) { receiver = writer; } abstract public void ExcuteCommand(); } /// <summary> /// 具体的命令类,调用接受者执行具体的方法 /// </summary> public class WriteErrorCommand : Command { private string msg; public WriteErrorCommand(Receiver writer, string msg) : base(writer) { this.msg = msg; } public override void ExcuteCommand() { receiver.WriteError(msg); } } public class WriteInfoCommand : Command { private string msg; public WriteInfoCommand(Receiver writer, string msg) : base(writer) { this.msg = msg; } public override void ExcuteCommand() { receiver.WriteInfo(msg); } }
下面定义最关键的Invoker,它负责将接受客户端的命令,然后将一批命令发送给执行者执行:
/// <summary> /// 下命令者,将命令加入或移出命令列表,执行列表中的命令 /// </summary> public class Invoker { private List<Command> commandList = new List<Command>(); public void AddCommand(Command cmd) { commandList.Add(cmd); } public void RemoveCommand(Command cmd) { commandList.Remove(cmd); } public void Notify() { foreach (Command cmd in commandList) { cmd.ExcuteCommand(); } } }
客户端调用:
Receiver writer = new Receiver(); Invoker logInvoker = new Invoker(); WriteErrorCommand writeError = new WriteErrorCommand(writer,"testError"); WriteInfoCommand writeInfo = new WriteInfoCommand(writer,"testInfo"); logInvoker.AddCommand(writeError); logInvoker.AddCommand(writeInfo); logInvoker.Notify();
执行结果如下:
Error: testError
Info: testInfo
命令模式的优点:1 比较容易的设计一个命令队列
2 可以较容易的将命令记入日志
3 允许接受请求的一方决定是否要否决请求
4 可以容易的实现对请求的撤销和重做
5 由于添加新的具体命令类不影响其他类,因此增加新的具体命令类很容易
6 把请求一个操作的对象和执行操作的对象分割开