将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

在GTA、巫师这一类游戏中,我们可以使用WASD操控角色的移动,我们也可以使用相同的按键操控载具、马匹的移动。无论是载具还是角色,当你按下了W键,它们都会执行了向前移动的指令。我们可以在代码中写出如下的代码:

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
38
39
void Update(){
if(CurrentControllingObject == Horse){
if(Input.GetKeyDown(KeyCode.W)){
HorseMoveForward();
}

if(Input.GetKeyDown(KeyCode.A)){
HorseMoveLeft();
}

if(Input.GetKeyDown(KeyCode.S)){
HorseMoveBackward();
}

if(Input.GetKeyDown(KeyCode.D)){
HorseMoveRight();
}
}

if(CurrentControllingObject == Hero){
if(Input.GetKeyDown(KeyCode.W)){
HeroMoveForward();
}

if(Input.GetKeyDown(KeyCode.A)){
HeroMoveLeft();
}

if(Input.GetKeyDown(KeyCode.S)){
HeroMoveBackward();
}

if(Input.GetKeyDown(KeyCode.D)){
HeroMoveRight();
}

....
}
}

这样的代码太丑陋了,但是更严重的问题是,这样的写法很不利于维护和拓展。想象一下,如果我们想让我们的游戏支持玩家自定义按键操作的功能,上面的代码根本就没办法实现,因为按键的绑定是被我们硬编码进脚本里的。而且,游戏中各种可以被控制移动的物体都被耦合在了一起,这不符合面向对象的设计原则。

因此,笔者希望通过本文介绍的命令模式解决上面两个问题:

  • 按键与游戏物体行为硬编码绑定
  • 所有游戏物体的行为处理逻辑耦合在了一起

命令模式