管理
1)命令处理器(Command Processor)模式将一个服务请求与其执行分开。一个命令处理器组件管理作为独立对象的请求,调度它们的执行,并且提供额外的服务。
2)视图处理程序(View Handler)模式帮助管理软件系统中的视图。视图处理程序组件允许客户机打开、处理和消除视图,协调视图之间的依赖性,并组织它们的更新。
3)备忘录(Memento)模式可以捕获并具体化一个对象的内部状态而无需破坏封装,以便其状态以后能够恢复。
命令处理器模式
模式描述的中心组件——命令处理器,维护了所有的命令对象。命令处理器安排命令的执行,可以存储它们供以后撤销之用,并且可能提供其他的服务。例如为了测试目的而记录命令顺序,每个命令对象将其任务的执行委托给应用程序功能核心内的供应者组件。
结构
抽象命令(abstract command)组件定义了所有命令对象的接口。这个接口至少由执行一条命令的过程组成,由命令处理器实现的额外服务要求进一步适用于所有命令对象的接口过程。
对于每个用户函数,我们从抽象的命令中导出命令组件(command component),一个命令组件通过使用零个或多个供应者组件(supplier component)实现抽象命令的接口。在执行之前,命令保存了相关的供应者组件状态,万一撤销可以恢复它。
控制器(controller)代表了应用程序的接口。它接受请求,并创建相应命令对象。命令对象随后被发送至命令处理器中执行。控制器维护了事件循环并将引入的事件映射到命令对象。
命令处理器(command processor)管理命令对象,调度它们并且开始它们的执行。这是实现与命令执行相关的附加服务的关键组件。命令处理器保持了特殊命令的独立性,因为它只使用了抽象的命令接口。命令处理器也同样存储已执行的命令以备后面的撤销操作使用。
供应者(supplier)组件提供了执行具体命令所需的绝大多数功能。相关联的命令通常共享供应者组件。在要求一个撤销机制时,供应者通常提供一种存储和恢复其内部状态的手段。
实现
1)定义抽象命令接口。抽象命令类隐藏了所有特殊命令的细节,这个类常常指定执行命令所需的抽象方法。它同样定义了由命令处理器提供的实现附加服务所需的方法。
2)对于应用程序支持的每个请求类型,设计命令组件。将一个命令捆绑到它的供应者上有几种选择方法。供应者组件可以在命令中强制编码,或者控制器可以给供应者提供命令构造函数作为一个参数。
3)通过提供宏命令增加了灵活性,宏命令结合了几个连续的命令。
4)实现控制器组件。命令对象由控制器创建,因为控制器已经从供应者组件中分离出来,所以这个附加的对控制器和命令的分离是可选的。
5)实现对命令处理器的附加服务的访问,一个用户可访问的附加服务通常由一个特殊命令类实现。
6)实现命令处理器组件。命令处理器从控制器中接收命令对象并对它们负责,对每个命令对象,命令处理器从调用do方法来开始执行。
优点
1)激活请求方法的灵活性。用来请求一个功能不同的用户界面元素可以产生相同类型的命令对象。这样容易将用户的输入重新映射到应用功能,这有助于创建一个适应用户偏好的应用程序界面。
2)请求数量和功能的灵活性。控制器和命令处理器独立于单个命令功能而执行,改变一个命令的实现或引入一个新的命令类都不会影响命令处理器或者应用程序中的其他不相关部分。
3)编程与执行相关的服务。命令处理器容易增加与命令执行相关的服务,它可以将命令记录或存储到一个文件以备以后检查或重放,可以编排命令并在稍后调度它们。
4)应用层的可测试性。命令处理器对于应用程序测试来说是一个理想的入口点。
5)并发性。命令处理器模式允许在分离的控制线程中执行命令。响应性得到改善是因为控制器不会等待到一个命令执行完成。然而,当应用程序的全局变量被几个并行执行的命令访问时,这就要求同步。
不足
1)效率损失。对能将组件分离的所有模式而言,附加的间接方法耗费了存储空间和时间。
2)潜在过多的命令类。一个具有丰富功能的应用程序可得出许多命令类。我们可以采取很多方法处理这种情况的复杂性:
·围绕抽象将命令分组。
·通过将供应者对象作为一个参数来传递,以统一非常简单的命令类。
·预先编程宏命令对象,它们依赖少数几个低层命令的结合。
·获得命令参数的复杂性。有些命令对象在执行之前或在执行期间检索来自用户的附加参数,这种情况使事件处理机制变得复杂,事件处理机制需要将事件传递到不同的目的地。