设计模式 学习笔记 之十三

第17章 Composite模式

我们常常会软件世界中观察到这样一种现象:把同种物体组合之后得到的组合物体跟构成它的单独的物体在行为上没有发生变化。举些例子来说明:如果你有几幅图片,你可以把它们组合起来形成一幅更大的图片;如果你有几个代数算式,你可以把它们组合起来形成一个更复杂的算式;如果你有几个2维图形,你可以把它们组合起来形成一个更大的2维图形;如果你有几条命令,你可以把它们组合起来形成一个更复杂的命令。

Composite模式正是用来对这种情况进行建模的模式。Composite模式要求组合体与个体之间在行为上没有本质差异,如果满足这个要求的话,那么就可以使用Composite模式。Composite模式带来的好处是简化了客户代码的逻辑,客户代码不需要知道它是在处理个体还是组合体,这种无差别处理给客户代码带来了便利。

下面我们来看一个例子。正如我们前面讲到的,我们可以把多条命令组合成一条命令,于是我们就有如下的设计。

clip_image002

另外再看一个例子。我们可以把单独的2维图形组合成一个更大的2维图形,如下图所示。

clip_image004

第18章 Observer模式

在许多事件驱动的系统中,常常需要把事件通知给对该事件感兴趣的实体。在这个模型中,事件的发布者一般被称为事件源,而对事件感兴趣的实体一般被称为观察者。我们希望事件源能够自动地把事件通知给每个观察者,不论这些观察者各自是哪些具体的对象。为了达到这个目的,我们可以为观察者规定一个抽象接口,所有的观察者都必须实现这个接口。观察者向事件源注册,表明自己对事件感兴趣。这样,当事件发生时,事件源就会通知每个已注册的观察者。这个设计可以用下面的图来表示。

clip_image006

这就是Observer模式,它是一种很常用的设计模式。我们下面来看看应用Observer模式的几个例子。

例子:定时器

定时器是一种事件源,它发布的事件就是“指定的时长已经过去”或“指定的时刻已经到达”。当事件发生时,定时器就把该事件通知给已注册的观察者,而观察者在收到通知时去执行相应的动作。在Java Swing中的Timer类就是一个这样的定时器。

clip_image008

例子:设备告警检测模块

假设我们在开发通信设备控制软件。在通信设备中,常常需要检测底层电信号或光信号的好坏,并在检测到异常时以某种方式发出告警,以引起用户的注意。我们现在就需要为通信设备设计它的告警检测模块。当前的问题是:我们无法预测告警模块在检测出告警时应该采取什么动作。例如,有的告警严重级别较高,需要将指示灯变红并发出警报声,而有的告警严重级别较低,只需要被记入告警日志中。为了让我们的告警检测模块能够尽可能地通用,我们可以把它设计成事件源,并向注册的观察者发布检测到的告警信息。于是有了下面的设计。

clip_image010

一点提醒

Observer模式是一种简单易用的模式,这个特点导致它常常被滥用。当Observer模式被滥用时,系统的复杂性不会降低反而会增加,这使得系统变得更复杂更难以维护。到底什么时候该用Observer模式?最关键的判断依据是:事件源无法预知事件发生时究竟会执行什么动作。如果满足这个条件,那么就应该使用Observer模式。但是如果事件源确切地知道当事件发生时应采取的动作,那么使用Observer模式就是画蛇添足,反而给系统带来不必要的复杂性。

posted @ 2011-05-15 18:51  李嘉 (Justin)  阅读(206)  评论(0编辑  收藏  举报