命令模式 简介

定义:

  • 将请求封装成对象,让你可以将客户端的不同请求参数化,并配合队列、记录、复原等方法来执行请求操作。

其核心就是,将逻辑封装到一个对象中。

命令模式是在开发编辑器类应用时常见的模式,它能很好地处理此类应用的“撤销、重做”操作。在游戏开发中这类模式并不常见,框架中引入命令模式是为了减少表现层的代码量。

要注意,命令模式的概念中不包含“撤销、重做”的概念,不要把命令模式的概念局限化了

Command模式快速入门

Command模式有经典的实现,不过经典实现一般都有一点门槛。这里给出一个比较容易理解的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface ICommand
{
void Execute();
}

public class OpenLightCommand : ICommand
{
public void Execute()
{
var light = GameObject.Find("Light");
light.SetActive(true);

Debug.Log("打开灯光");
}
}

void Start()
{
var command = new OpenLightCommand();
command.Execute();
}

这是非常简单的命令模式的实现,舍去了一些经典模式中的缓存操作的逻辑。

决定版架构中的命令模式

决定版架构中的Command是用来操作Model层的。

不只是决定版架构,uFrame、StrangeIOC、PureMVC、以及CQRS原则都是使用Command来操作Model层的。

使用Command操作Model,在日常开发中并不常见,这些框架都使用Command,就是为了分担Controller的交互逻辑。

并且Command还有更多的好处

Command模式的更多好处

其中一个好处就是将逻辑封装到对象中的好处,这样更方便管理。

比如我们要实现按顺序执行3~4个Model操作,其实也可以按照顺序执行封装好的Command指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

public interface ICommand
{
void Execute();
}
public class ACommand : ICommand
{
public void Execute()
{
Debug.Log("Execute A Command");
}
}
public class BCommand : ICommand
{
public void Execute()
{
Debug.Log("Execute B Command");
}
}
public class CCommand : ICommand
{
public void Execute()
{
Debug.Log("Execute C Command");
}
}

void Start()
{
var commands = new List<ICommand>();
commands.Add(new ACommand());
commands.Add(new BCommand());
commands.Add(new CCommand());

commands.ForEach(c => c.Execute());
//List<T>.ForEach(Action),是List基类自带的方法
}

代码很简单,就是按照顺序执行每一个指令。

使用命令模式可以很轻松地实现这样的功能,这就是命令模式的其中一个好处。

小结

  • MVC中的命令模式
    • 专注操作Model与发送事件来通知Controller更新View,使Controller不再那么臃肿
    • 以对象为单位管理逻辑,可以实现比较复杂的功能。