游戏编程模式:命令模式

在命令模式中,将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

模式动机:

将命令的调用端、命令以及命令的接受端分开,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。

命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。

模式定义:

命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

模式优点:

在命令与角色之间加入的间接层使得我们可以让玩家控制游戏中的任何角色,只需通过改变命令执行时传入的角色对象即可。

一些代码生成命令并将它们放置于命令流中,一些代码执行命令并且调用它们,通过中间的队列,我们将生产者端和消费者端解耦。

撤销与重做:

一个命令代表了一个可重用的对象,表示一件可完成的事情。前面的输入处理程序仅维护单一的命令对象,并在对应按钮被按下的时候调用其execute()方法。

支持一次撤销的时候,我们可以保留它们上一个命令,当输入撤销指令的时候,就会调用undo方法;如果想支持多次撤销,我们将维护一个命令列表和一个对“当前”命令的一个引用,每当玩家执行了一个命令,我们就将这个命令添加到列表中,并把current指向它。

模式分析:

命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。

  • 每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
  • 命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
  • 命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
  • 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

缺点:

  • 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用场景:

  • 需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互;需要在不同的时间指定请求、将请求排队和执行请求;需要支持命令的撤销操作和恢复操作,需要将一组操作组合在一起,即支持宏命令。