命令模式

概念
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。
在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。
Command模式可应用于
a)整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。
b)调用前后需要对调用参数进行某些处理。
c)调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。
Command模式有如下效果:
a)将调用操作的对象和知道如何实现该操作的对象解耦。
b)Command是头等对象。他们可以像其他对象一样被操作和扩展。
c)你可将多个命令装配成一个符合命令。
d)增加新的Command很容易,因为这无需改变现有的类。
首先我在这里定义一个抽象类Command
1 public abstract class Command 2 { 3 public abstract void Execute(); 4 }
然后在定义一个调用者Invoker对象,供客户端调用,该调用者有个SetCommand方法用于设置命令对象,设置成功后通过Action()来执行具体的命令
1 public class Invoker 2 { 3 private Command _Command { get; set; } 4 public void SetCommand(Command command) 5 { 6 this._Command = command; 7 } 8 9 public void Action() 10 { 11 this._Command.Execute(); 12 } 13 }
接着我在这里定义一个接受者对象Receiver,接受者对象执行具体的操作
1 public class Receiver 2 { 3 public void DoWork() 4 { 5 Console.WriteLine("接收"); 6 } 7 }
再接着,定义一个具体的命令对象ConcreteCommand,对接收着的动作行为进行封装
1 public class ConcreteCommand : Command 2 { 3 Receiver _Receiver { get; set; } 4 public ConcreteCommand(Receiver receiver) 5 { 6 this._Receiver = receiver; 7 } 8 public override void Execute() 9 { 10 _Receiver.DoWork(); 11 } 12 }
在这里,我们可以看出,具体命令的执行由接受者Receiver决定
最后看下客户端调用的例子
1 static void Main(string[] args) 2 { 3 Receiver receiver = new Receiver();//接收者 4 Command command = new ConcreteCommand(receiver); 5 //客户端直接执行具体命令方式(此方式与类图相符) 6 command.Execute(); 7 8 //客户端通过调用者来执行命令 9 Invoker invoker = new Invoker();//调用者 10 invoker.SetCommand(command); 11 12 invoker.Action(); 13 Console.Read(); 14 }
从例子中,我们可以看出:调用者Invoker是一个包含命令的容器,通过通知调用者Invoker去触发Action方法,调用者可以自己找到具体的命令对象去,由命令对象去寻找具体的接受者Reciver来执行响应的操作。
再举个例子:加入现在有台电视。大家都知道,我们可以通过遥控器去控制一台电视机,在这里,遥控器、电视机、就分别充当着Invoker和Reciver的角色。而遥控器上面的按键内部所触发的具体的命令就是命令对象。在这个Invoker中有多个的Command对象,不同的对象由Invoker上不同的方法(按键)进行触发。在这个例子里。Invoker只知道某个按键即某个方法具体触发的命令对象是谁,但是不知道命令对象的接受者。这个接受者Receiver只有具体的命令Command才知道的。这就是命令模式实现的Invoker和Receiver之间的解耦。
文章参考:

浙公网安备 33010602011771号