Pattern-Oriented Software Architecture v1巨详细读书笔记 2

POSA vol.1 [page 276--281]

------------------------------------------------

[270] 

……
(--跳过了部分proxy变体,例子和已知应用--)




[276]
3.5管理
一个系统通常处理一组类似的对象、服务,甚至复杂的组件。从用户或者其他系统输入的事件需要解析并安排好,这就是个例子。另外一个例子是,交互系统需要将特定应用程序的数据通过不同方式呈现出来,这些视图独立或整体地都能得到适当处理。

在结构良好的系统中,通常需要独立的‘manager’组件处理类似的一组对象,在这里描述两种此类设计模式:
    - Command Processor 将一个服务的请求与执行分离,一个Command Processor组件把请求作为独立的对象来管理,安排它的执行,并提供附加的服务,比如:将请求对象存储起来供撤销时使用。

    - View Handler 帮助软件系统管理视图,允许客户打开、操作、排列视图,协调相互依赖的视图,并组织他们更新。

Command Processor 模式和Command模式[GHJV95]都采用将服务请求封装进一个命令对象的概念,然而,Command Processor把Command模式嵌入进了管理命令对象的结构中。在[GHJV95]中也描述了另外了的管理模式,Memento:
    - Memento 允许你在不破坏封装性的前提下使一个对象的的内部状态能被捕获,并存储下来。
Memento帮助你管理特定组件的状态,例如:在撤销已经执行的操作时需要恢复组件状态,或者客户端需要在不破坏封装性的前提下访问组件的状态。Memento提供给客户端拷贝当前状态的功能。


[277]
[Command Processor]
Command Processor 设计模式 将一个服务的请求与执行分离,一个Command Processor组件把请求作为独立的对象来管理,安排它的执行,并提供附加的服务,比如:将请求对象存储起来供撤销时使用。

[例子]
文本编辑器通常允许用户修正自己的失误,比如:撤销最近作的修改,甚至允许撤销很多步的修改。我们要开发这样的一个编辑器,让我们叫他TEDDI。
TEDDI的设计中包括了多步撤销的机制,并允许在以后增强功能,比如:添加新的特性,或者允许批量的操作。
TEDDI的界面提供了多种交互方式,比如:键盘输入或者弹出菜单。在程序中要定义一个或多个回调过程,这些回调过程将会在人机交互时自动被调用。



[278]
[问题]
An application that includes a large set of features benefits from a
well-structured solution for mapping its interface to its internal
functionality. This allows you to support different modes of user
interaction, such as pop-up menus for novices, keyboard shortcuts
for more experienced users, or external control of the application via
a scripting language.
为了执行用户请求,你经常需要在系统中实现一些核心功能以外的服务,如:撤销,重做,批量宏,活动日志,请求的调度和暂停。
The following forces shape the solution:
    - 不同的用户喜欢用不同的方式使用应用程序
    - 增强已有的应用程序不应该破坏已有的代码
    - 如撤销这样的附加服务应该‎对所有的请求都实现成一致的。

[解决方案]
Command Processor模式基于Command模式[GHJV95],两种模式都采用了将请求封装进对象的概念,当用户调用应用程序的特定功能时,请求都被转 变成一个command对象,Command Processor模式更明确地阐明了command对象是怎么被管理的。在[参见]一节将会讨论两种模式的不同。

Command Processor 是此模式的中心组件,它会照料所有的command对象,会调度command的执行,也许会存储这些command命令用以撤销操作,也可能会为了测试 的目的在日志中记录command的运行序列。每个command对象都将它任务的执行代理给在应用程序功能核心中的supplier组件。

[结构]
Abstract command 组件定义了所有command对象的接口,最少包含了一个执行此命令的方法,若需要享受command processor提供的附加服务,则需要此接口给所有的command对象定义更多的方法,如:TEDDI中的abstract command类就定义了一个附加的undo方法。
[279]
对于每个用户功能我们都从abstract command继承一个command组件,并实现接口中的方法,在这个command组件中会用到多个(0..n)个supplier组件。TEDDI 的command组件会在执行之前保存相关的supplier组件状态,在撤销的时候会恢复这些状态,例如,删除命令将负责存储删除掉的文本和其在整个文 档中的位置。
[图]
Controller表示应用程序的界面,它接收如‘粘贴文本’这样的请求,并创建相应的command对象,把此command交付给command processor去执行。TEDDI的controller维护事件循环,并映射输入事件为一个command对象。
Command Processor 管理command对象,调度并执行他们,它是实现执行command的附加服务的关键组件,它能保持独立于特定的command的原因在于它只使用 abstract command接口。在TEDDI中,command processor也存储已经执行的command用于撤销功能。
Supplier 组件提供大部分执行具体command的功能(具体command是相对于abstract command而言的),有关联的command通常共享supplier组件。当需要撤销机制时,supplier通常提供保存和恢复内部状态的方法。 TEDDI中主要的supplier组件实现的是内部文本的表示。

[280]
[图]
下图显示了本模式中组件间的主要关系,并用“撤销“作为一个command processor提供的附加服务的例子。
[图]

[281]
[动态]
下图显示了实现“撤销”机制的command processor的典型场景。一个将选定的单词变成大写的请求到达,被执行,然后又被撤销,将会出现以下步骤:
    - controller从事件循环中接收用户输入的请求,并创建一个名为‘capitalize’的command对象。
    - controller将新生成的对象传给command processor进一步处理。
    - command processor激活command的执行,并把command存储起来以备撤销。
    - 名为‘capitalize’的command对象从它的supplier中获得当前选择的文本,将文本以及文本所在文档中的位置保存下来,并请求supplier将选定的文本变成大写。
    - 接收到‘撤销’操作后,controller将此请求传给command processor,它会执行最近执行的command的撤销操作。
    - 名为‘capitalize’的command对象将设置supplier的状态为之前的状态,这将通过在原始位置把文本替换成保存下来的原始文本来实现。
    - 如果在此command对象上没有更多的动作请求可能,则从command processor中删除此command对象。
[图]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值