Java基础笔记 - JDK中提供的观察者模式支持

JDK中也提供了对观察者模式的内置支持。

1、JDK中观察者模式的实现原理:

Observable类用于创建可以观测到你的程序中其他部分的子类。当这种子类的对象发生变化时,观测类被通知。观测类必须实现定义了update()方法的Observer接口。当一个观测程序被通知到一个被观察对象的改变时,update()方法被调用。

2、Observable类:

public class Observable
extends Object

此类表示模型视图范例中的 observable 对象,或者说“数据”。可将其子类化,表示应用程序想要观察的对象。

一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。

2.1、相关方法:

addObserver
public void addObserver(Observer o)

如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。未指定向多个观察者发送通知的顺序。请参阅该类的注释。

参数:
o - 要添加的观察者。

抛出:
NullPointerException - 如果参数 o 为 null。

notifyObservers
public void notifyObservers()

如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。

每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 null。换句话说,此方法等效于:
notifyObservers(null)

notifyObservers
public void notifyObservers(Object arg)

如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。

每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 arg 参数。

参数:
arg - 任意对象。

notifyObservers()有两种形式:一种带有参数而另一种没有。当用参数调用notifyObservers()方法时,该对象被传给观测程序的update()方法作为第二个参数。如果调用无参数的notifyObservers()方法,则将update()方法传递一个null,可以使用第二个参数传递适当于你的应用程序的任何类型的对象。

setChanged
protected void setChanged()

标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true。

3、Observer接口:

public interface Observer

一个可在观察者要得到 observable 对象更改通知时可实现 Observer 接口的类。

3.1、相关方法:

void update(Observable o,
Object arg)

只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以便向所有该对象的观察者通知此改变。

参数:
o - observable 对象。
arg - 传递给 notifyObservers 方法的参数。

4、被观察对象的工作原理按照如下规则:

如果它被改变了,它必须调用setChanged()方法。

当它准备通知观测程序它的改变时,它必须调用notifyObservers()方法。该方法导致了在观测对象中对update()方法的调用。

注意:当对象在调用notifyObservers()方法之前没有调用setChanged()方法,就不会有动作发生。

也就是说在update()方法被调用之前,被观测对象必须调用setChanged()和notifyObservers()两个方法。

5、下面写一个例子实现从被观察对象向观察者发送执行动作:

被观察者:

/*
\
被观察者
*/
public class Monitored extends Observable {

public void sendMessage(String str){
    this.setChanged();
    this.notifyObservers(str);
}

}

观察者1:

/*
\
观察者1
*/
public class Watcher1 implements Observer {

@Override
public void update(Observable o, Object arg) {
    System.out.println("Watcher1 receive:" \+ (String)arg);
}

}

观察者2:

/*
\
观察者2
*/
public class Watcher2 implements Observer {

@Override
public void update(Observable o, Object arg) {
    System.out.println("Watcher2 receive:" \+ (String)arg);
}

}

在客户端使用观察者角色:

public static void main(String[] args) {
//创建被观察对象
Monitored monitored = new Monitored();
//创建两个观察者
Watcher1 watcher1 = new Watcher1();
Watcher2 watcher2 = new Watcher2();
//添加观察者
monitored.addObserver(watcher1);
monitored.addObserver(watcher2);
//被观察者发送消息给观察者
monitored.sendMessage(“这是一条消息”);
}

arthinking wechat
欢迎关注itzhai公众号