命令模式(三)命令与执行分离
命令与执行分离特性
命令模式有一个特性就是“命令”与“执行”分离。
在日常编程中,命令 与 执行 不分离的代码是很常见的,其中最典型的就是方法直接调用
1 | void SayHello(){ |
如果想要让命令与执行分离,我们可以用消息机制:
1 | public class SayHelloEvent{} |
这里使用的是
SimpleEventSystem
,是比TypeEventSystem
更方便的消息系统,其中的AddTo
方法相当于UnregisterWhenGameObjectDestroyed
也就是消息机制本身的设计思想就是命令与执行分离,每个事件的发布只需要判个空就可以了,不需要关注监听的内容,我们可以在自定义的地方发布指定的事件。
我们再看下使用命令模式实现的命令与执行分离的代码,如下:
1 | public interface ICommand |
我们的命令只需要new一个Command并调用Execute就能执行了,但是执行的内容是在具体对象内部创建的,我们可以在自定义的地方new 这个Command。
三者之间的区别
- 方法:命令与执行在一起,没有分离
- Command:执行在Command内部实现(有分离)
- 事件机制:执行在事件注册中实现(有分离)
Command的命令与执行分离的程度,介于方法与事件机制之间。
事件机制也能达到命令与执行分离的效果,但是事件机制一般至少需要通过两个对象才能完整使用。一个是执行对象(监听/注册)、一个是命令对象(发布)
而Command的命令与执行分离不同,可以在自定义的位置和时机执行指令。
空间与时间上的命令与执行分离
上面介绍的命令与执行的分离,指的是空间上命令与执行分离,也就是说命令的位置和执行的位置不同。
简单的延时
而我们只要加上自己的延时方法,就可以实现时间上的分离
1 | public interface ICommand |
Observable是UniRx的概念。这里表示这个方法1秒后执行。
TimeSpan
是C#内表示时间长度的单位,TimeSpan.FromSeconds(1.0f)
表示时长为1秒的时间长度。它是UniRx的Timer需要的参数。
除了可以简单地延时之外,还可以做成命令队列:
1 | public interface ICommand |
这是非常简单的一个命令队列,这种命令队列在一些需要跨线程、跨平台通信情况下非常常见。
代码中我们可以控制每一个Command,做到每一帧执行一个Command的程度,这也是符合时间上命令与执行分离。
知道了这些后,我们可以用命令来做一个异步的消息同步,也可以写带延时的命令
小结
- 命令与执行分离
- 三个程度
- 方法
- 命令与执行是在一起的,命令调用时,方法就执行了
- Command
- 命令与执行是分离的,执行的逻辑是在Command内部
- 事件机制
- 命令与执行是分离的,但是需要至少两个对象才能完成一个完整的通信逻辑
- 方法
- 三个程度
- 空间与时间上的分离
- 空间上
- 命令与执行的代码在不同的位置
- 时间上
- 控制执行时机在某一时刻
- 空间上