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

来源:互联网 发布:windows qt开发环境 编辑:程序博客网 时间:2024/04/24 20:58

GoF的Observer有没有什么变体存在,他的别名可以叫什么?在本笔记中,Publisher-Subscriber(出版-订阅)模式为这些问题做了完美解答。在笔记的最后还描述了Pattern System(模式系统)的定义。
本段笔记是《Pattern-Oriented Software Architecture vol.1 A system of patterns》原书[page 332-362]的山寨翻译:),包括了Publisher-Subscriber(出版-订阅)模式完整的描述。同时,笔记跳过了Idiom一章,在最后描述了Pattern System的定义。
《Pattern-Oriented Software Architecture vol.1 A system of patterns》一书后半部分在这一笔记中就全部结束了,在这之后,工作开始忙起来了,我不一定能继续按时更新读书笔记,但我会尽最大的努力将读书笔记写下去,我的下一个读书计划是《POSA v2》,其主要内容描述了关于分布式和并发系统的模式。
---------------------------------------

[page 332]
……
[page 339]
[Publisher-Subscriber(出版-订阅)]
Publisher-Subscriber模式单向传播变动(one-way propagation of changes):一个publisher状态有变动,将会通知给任意数量的subscriber。这样能帮助正在协作的各组件保持状态同步。
[别名]
Observer,Dependents
在这一节我们给出了一个基于[GHJV95]中的Observer模式的简短的模式描述,其中加入了我们的观点,并描述了它的变体。
[问题]
经常出现这种情况:数据在一处被改变,此变化需要在多个依赖于此数据的组件中同时反应出来。用户界面元素是一个典型例子:当内部数据变化时,所有依赖于此数据的视图都要更新。我们可以引入依赖于数据的直接调用来解决此问题,但是这种解决方案不够灵活并且也不能重用,我们将探讨适合多种环境的更通用的更改-传播机制。
解决方案需要平衡以下条件(forces??):
  1 当一个特定组件中的状态改变时,多个(1-N)组件能获得关于此变化的通知。
  2 依赖于数据的组件个数和组件的标识,在事先并不知道,他们甚至会随时变化。
  3 不能让依赖于数据的组件主动轮询是否有新信息。
  4 在引入更改-传播机制后,不能让publisher和依赖于它的组件之间耦合太紧密。

[解决方案]
一个专用的组件扮演publisher的角色(在[GHJV95]中叫做subject),其他依赖于publisher,关注它变化的组件作为subscriber(在[GHJV95]中叫做observer)。
publisher维护了一个注册表,其中注册了所有当前在此publisher上订阅内容的组件。当一个组件想成为subscriber,它可以用publisher提供的订阅接口订阅。类似的也可以取消订阅。

[page 340]
当publisher状态改变时,它会通知所有的subscriber,subscriber会反过来在修改过的数据中获取它们关心的数据。
实现此模式时,有以下的自由度:
  - 可以像[GHJV95]描述的一样,引入抽象类,让不同的类成为publisher或subscriber。
  - publisher能决定哪些内部状态改变时才通知他的subscriber(observer),也可以在调用notify()之前将多个改变存放到队列中。
  - 一个对象能做为多个publisher的subscriber。
  - 一个对象可同时扮演publisher和subscriber两种角色。
  - 可以用事件类型来区分不同的订阅和随后的通知,使subscriber可以只获得它所关心的事件信息。
  - 在通知subscriber时,publisher可以选择只发送变化的数据;也可以只通知subscriber有改变,让它自己来查找有哪些变化。

对于变动通知和数据获取方式,通常有两种模型:push模型和pull模型。在push模型中,当publisher通知subscribers时,publisher同时会将所有变化的数据发送给它,subscriber只是能取得数据但是不能选择是否(或何时)获取数据。在pull模型中,publisher在发送变动通知时,只发送最少的信息,subscriber会负责获取它需要的数据。当然在这两种极端的模型之间也有许多折衷的变体。
push模型有非常刻板的动态行为,而pull模型虽然在publisher和subscriber之间传递大量的消息,但也更灵活。

对于复杂的数据变动,应用push模型不是一个好选择,特别是当publisher发送一个subscriber并不感兴趣的大数据包给它时,push模型的劣势显得尤为突出,甚至只是push一个描述变更数据种类的数据包都显得额外开销太大。在这种情况下,应该采用pull模型,让subscriber自己来找出哪些数据发生了变化,可以像决策树一样组织连续地查找出数据变化细节的过程。
[page 341]
通常,当subscriber在大多数时间都需要发布的信息时,push模型才是比较好的选择。当只有独立的subscriber能决定是否(或何时)需要特定的某片信息时,才采用pull模型。

[变体]

- Gatekeeper
(??Gatekeeper. The Publisher-Subscriber pattern can be also applied to distributed systems. In this variant a publisher instance in one process notifies remote subscribers. The publisher may alternatively be spread over two processes. In one process a component sends out messages, while in the receiving process a singleton 'gatekeeper' demultiplexes them by surveying the entry points to the process. The gatekeeper notifies event-handling subscribers when events for which they registered occur. The Reactor pattern ISch94) describes this scheme in detail.)
Publisher-Subscriber模式也适合于分布式系统。此变体中,位于一个进程中的publisher实例会通知远程的subscriber。publisher也可以分布在两个进程中,一个进程中的组件发送消息,而在另一个接收进程中,作为单件的gatekeeper将接收到消息的通过其入口点多路分解,当subscriber注册的事件出现时,gatekeeper通知相应的subscriber。[SCH94]的Reactor模式详细地描述了此方案。

- Event Channel
此变体在OMG的Event Service Specification[OMG95]中提出,它是面向分布式系统的,此模式最大限度地解除了publisher和subscriber之间的偶合性。subscriber只关心数据出现了变化,但是不关心是哪个组件的数据变化了。publisher也不关心哪些组件是subscriber。

在此变体中,event channel在publisher和subscriber之间被创建并置于其间。相对于publisher来说,event channel是一个subscriber,而对于subscriber来说,它就是一个publisher。如下图所示,subscriber会注册到event channel中。It asks an administration instance to create a 'proxy publisher', and connects it over a process boundary with a local 'proxy subscriber'. Analogously, a 'proxy subscriber' is created between a publisher and an event channel and, on the event channel side, a 'proxy publisher'.
通过这种方法,publisher,event channel和subscriber都可以分布在不同的进程中。
[page 342]
[图]
在event channel中增加一个消息buffer可以进一步解除publisher和subscriber之间的耦合性,当从publisher发出的消息到达event channel时,它并不需立即通知subscriber,而是根据某种通知策略在之后某个时间通知subscriber。

你甚至可以将多个event channel串联起来,因为event channel可以提供事件过滤等(or storing an event internally for a fixed period and sending it to all components that subscribe during that period,This is often referred to as 'quality-of-service'.)附加功能。串起来的event channel能像UNIX的pipe一样,将多个独立的event channel的功能汇集起来完成系统所需的功能。

The Event Channel variant is powerful enough to allow multiple publishers and typed events.

- Producer-Consumer
另一个变体采用生产者与消费者这种协作方式,producer供应信息,而consumer接收信息并处理,通过在这两者之间设置一个buffer,可以解除他们之间的耦合性。producer在不关心consumer的情况下写buffer,而consumer也自己决定何时从buffer取数据,他们之间只有在检查buffer已满或为空时才会进行同步。producer检测到buffer已满时会暂停,consumer检测到buffer为空时也会停下来等待有数据到来。Publisher-Subscribe和Producer-Consumer之间的另一个不同点在于Producer和consumer通常是1:1的关系。
[page 343]
(??Only more complex patterns such as Event-Channel can simulate a Producer-Consumer relationship with more than one producer or consumer.)只有像Event-Channel这样的更复杂的模式才能用多个Producer或consumer模拟Producer-Consumer模式。多个Producer都能提供数据,但是只允许他们串行地采用直接或间接的方式往buffer写数据。多个consumer会稍复杂些,一个consumer从buffer读取数据时,并不从buffer删除数据,只是将此数据标志成此consumer已读,给此consumer造成已经消费了数据并且数据已经被删除的假象,而给其他consumer数据仍然存在而且可读的假象。Iterator是实现此行为的一种好方法,每个consumer在buffer上都有它自己的iterator,iterator的位置反映了相应的consumer在buffer上已经读取过多少数据,而在后台buffer有一个迟后的iterator,在所有buffer上的读操作都完成后负责清除数据。
[page 344 空白]


[page 345]
4 Idiom(习语,成语,方言)
(跳过这一章)
……

[page 359]
5 Pattern System(模式系统)
很多独立的模式结合在一起构成Pattern System。Pattern System描述了系统中各成分模式是如何连接在一起的,如何实现这些模式,以及如何开发支持模式的软件系统。Pattern System是表示和构建软件架构的一种强大的工具。
In this chapter we specify a pattern system that includes the patterns we describe in this book, and that is open for the integration of other patterns, for example those from [GHJV95], [PLoP94] and [PLoP95]. as well as your own patterns.

5.1 什么是Pattern System?
模式不是独立存在的——他们之间有许多关联性,虽然模式都是像目录一样简单列举出来的,但是这并不影响他们之间的多种关系,各种模式在Pattern System中都有错综复杂的关系。
Pattern System将很多独立的模式结合在一起,描述了模式间如何连接和互补,Pattern System也为我们在软件开发过程中如何有效地应用各种模式提供了支持。

Christopher Alexander采用‘language’而不是‘system’来描述同样的概念,[Ale79]p.185:
  The elements [of a pattern language] are patterns. There is a structure on the patterns, which describes how each pattern is itself a pattern of other smaller patterns. And there are also rules, embedded in the patterns, which describe the way that they can be created, and the way that they must be arranged with respect to other patterns.

  However, in this case, the patterns are both elements and rules, so rules and elements are indistinguishable. The patterns are elements. And each pattern is also a rule, which describes the possible arrangements of the elements-themselves again or other patterns.
的确,Pattern System可被比作一门语言,各种模式构成了此语言的词汇表,而他们实现及组合的规则构成了它的语法。

我们更喜欢使用术语‘Pattern System’而不是‘Pattern language’。……

[page 361]
术语‘Pattern System’定义如下:
  一个软件架构Pattern System,是一组描述了软件开发过程中模式实现、组合及实践指南的软件架构模式集合,

软件架构Pattern System的主要目的是为开发高质量的软件提供提供支持,‘高质量’意味着系统必须同时满足功能和非功能需求。为了达到此目的,Pattern System需要满足以下需求:
  - 应该包含足够的模式基础。……
  - 应该按照统一格式描述所有的模式。……
  - 应该揭示出模式间各种关系。……
  - 应该将各组成模式组织起来。……
  - 应该为软件系统的构建提供支持。……
[page 362]
  - 应该支持进化。……
本书以及很多相关的著作中都提供了大量的模式,这些模式覆盖了很广的范围,致力于解决许多软件架构中的问题,这已经满足了第一条需求,
……
……
……

 

原创粉丝点击