游戏开发中用到的设计模式——命令模式(一)
一,命令模式的定义
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。解决了这种耦合的好处我认为主要有两点:1.更方便的对命令进行扩展(注意:这不是主要的优势,后面会提到)2.对多个命令的统一控制(这种控制包括但不限于:队列、撤销/恢复、记录日志等等)。在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。
a)整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。
b)调用前后需要对调用参数进行某些处理。
c)调用前后需要进行某些额外处理,比如参数合法性验证,日志,缓存,记录历史操作等。
Command模式有如下效果:
a)将调用操作的对象和知道如何实现该操作的对象解耦。
b)Command是头等对象。他们可以像其他对象一样被操作和扩展。
c)你可将多个命令装配成一个符合命令。
d)增加新的Command很容易,因为这无需改变现有的类。
经典的命令模式包括4个角色:
Command:定义命令的统一接口
ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
Receiver:命令的实际执行者
Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。
经典的命令模式包括4个角色:
ICommand接口:定义命令的统一接口
ConcreteCommand具体的命令实现类:ICommand接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
Receiver:命令的实际执行者
Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。
下面对上面四个角色的经典实现用代码来进行说明,这也是大部分文章对命令模式的运用方式。
| public interface ICommand
{ void Execute(); }
public class ConcreteCommandA : ICommand { private Receiver receiver = null;
public ConcreteCommandA(Receiver receiver) { this.receiver = receiver; }
public void Execute() { this.receiver.DoA(); } }
public class ConcreteCommandB : ICommand { private Receiver receiver = null;
public ConcreteCommandB(Receiver receiver) { this.receiver = receiver; }
public void Execute() { this.receiver.DoB(); } }
public class Receiver { public void DoA() { //DoSomething }
public void DoB() { //DoSomething } }
public class Invoker { private ICommand command = null;
//设置命令 public void SetCommand(ICommand command) { this.command = command; } //执行命令 public void RunCommand() { command.Execute(); } } public class Client { public Client() { Receiver receiver = new Receiver(); Invoker invoker = new Invoker(); invoker.SetCommand(new ConcreteCommandA(receiver)); invoker.RunCommand(); invoker.SetCommand(new ConcreteCommandB(receiver)); invoker.RunCommand(); } } |
不知道大家看过上面的代码之后是什么感觉,反正我看过上面的代码之后第一反应确实是越看越糊涂了,主要觉得有几点疑问:
1. 执行命令可以,但是为什么要用命令封装起来,这不是有点脱裤子放屁的感觉么?我完全可以这样写:
|
public class Client { public Client() { Receiver receiver = new Receiver(); receiver.DoA(); receiver.DoB(); } } |
这样不是更加简单明了?两个类搞定。
后续内容请参照:http://www.youxijishu.com/h-nd-135-2_323.html
更多游戏技术资料请参照游戏技术网::http://www.youxijishu.com
浙公网安备 33010602011771号