专业化模式另一特点是删除了 ConcreteObserver 的成员变量 observerState。有时候具体观察者并不需要保存Subject的最新
状态,而只需要监测状态更新时 Subject 的状态。例如,如果观察者将成员变量的值更新到标准输出上,就可以删除
observerState,这样一来就删除了ConcreteObserver和State类之间的关联。
更常见的命名规则更常见的命名规则
经典模式甚至是前文提到的专业化模式都用的是attach,detach和observer等术语,而Java实现中很多都是用的不同的词典,
包括register,unregister,listener等。值得一提的是State是listener需要监测变化的所有对象的统称,状态对象的具体名称需
要看观察者模式用到的场景。例如,在listener监听事件发生场景下的观察者模式,已注册的listener将会在事件发生时收到通
知,此时的状态对象就是event,也就是事件是否发生。
平时实际应用中目标的命名很少包含Subject。例如,创建一个关于动物园的应用,注册多个监听器用于观察Zoo类,并在新
动物进入动物园时收到通知。该案例中的目标是Zoo类,为了和所给问题域保持术语一致,将不会用到Subject这样的词汇,
也就是说Zoo类不会命名为ZooSubject。
监听器的命名一般都会跟着Listener后缀,例如前文提到的监测新动物加入的监听器会命名为AnimalAddedListener。类似
的,register,、unregister和notify等函数命名常会以其对应的监听器名作后缀,例如AnimalAddedListener的register、
unregister、notify函数会被命名为registerAnimalAddedListener、 unregisterAnimalAddedListener和
notifyAnimalAddedListeners,需要注意的是notify函数名的s,因为notify函数处理的是多个而非单一监听器。
这种命名方式会显得冗长,而且通常一个subject会注册多个类型的监听器,如前面提到的动物园的例子,Zoo内除了注册监听
动物新增的监听器,还需注册监听动物减少监听器,此时就会有两种register函数:(registerAnimalAddedListener和
registerAnimalRemovedListener,这种方式处理,监听器的类型作为一个限定符,表示其应观察者的类型。另一解决方案是
创建一个registerListener函数然后重载,但是方案一能更方便的知道哪个监听器正在监听,重载是比较小众的做法。
另一惯用语法是用on前缀而不是update,例如update函数命名为onAnimalAdded而不是updateAnimalAdded。这种情况在监
听器获得一个序列的通知时更常见,如向list中新增一个动物,但很少用于更新一个单独的数据,比如动物的名字。
接下来本文将使用Java的符号规则,虽然符号规则不会改变系统的真实设计和实现,但是使用其他开发者都熟悉的术语是很
重要的开发准则,因此要熟悉上文描述的Java中的观察者模式符号规则。下文将在Java8环境下用一个简单例子来阐述上述概
念。
一个简单的实例一个简单的实例
还是前面提到的动物园的例子,使用Java8的API接口实现一个简单的系统,说明观察者模式的基本原理。问题描述为:
创建一个系统zoo,允许用户监听和撤销监听添加新对象animal的状态,另外再创建一个具体监听器,负责输出新增动物的
name。
根据前面对观察者模式的学习知道实现这样的应用需要创建4个类,具体是:
Zoo类:即模式中的主题,负责存储动物园中的所有动物,并在新动物加入时通知所有已注册的监听器。类:即模式中的主题,负责存储动物园中的所有动物,并在新动物加入时通知所有已注册的监听器。
Animal类:代表动物对象。类:代表动物对象。
AnimalAddedListener类:即观察者接口。类:即观察者接口。
PrintNameAnimalAddedListener:具体的观察者类,负责输出新增动物的:具体的观察者类,负责输出新增动物的name。。
首先我们创建一个Animal类,它是一个包含name成员变量、构造函数、getter和setter方法的简单Java对象,代码如下:
public class Animal {
private String name;
public Animal (String name) {
this.name = name;