- 侦听事件驱动程序中的外部事件
- 侦听/监视某个对象的状态变化
- 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品, 消息的出现等等)被触发时,通知邮件列表中的订阅者
JDK对观察者模式的实现.Observer观察者与Observable被观察者
public class Client {
public static void main(String[] args) {
NewsPublisher publisher = new NewsPublisher();
//添加观察者对象
publisher.addObserver(new SubscriberObserver());
publisher.addObserver(new ManagerObserver());
//发布新闻,触发通知事件
publisher.publishNews("Hello news", "news body");
}
}
//被观察者
class NewsPublisher extends Observable {
public void publishNews(String newsTitle, String newsBody) {
News news = new News(newsTitle, newsBody);
setChanged();//标明对象的状态已发生变化
System.out.println("News published:" + newsTitle);
this.notifyObservers(news);//通知各Observer,并发送一个名为news对象的消息
//other process ... such as save news to database
}
}
//观察者
class SubscriberObserver implements Observer {
public void update(Observable observee, Object param) {
if (param instanceof News) {
mail2Subscriber((News)param);
}
}
private void mail2Subscriber(News news) {
System.out.println("Mail to subscriber. A news published with title:" + news.getTitle());
}
}
//观察者
class ManagerObserver implements Observer {
public void update(Observable observee, Object param) {
if (param instanceof News) {
mail2Manager((News)param);
}
}
private void mail2Manager(News news) {
System.out.println("Mail to Manager. A news published with title:" + news.getTitle());
}
}
一般优先选择jdk已经提供的方式.当然我们也可以自己实现.在此之前不妨看看jdk 关于observer与observable的代码实现.
public interface Observer {
//这个方法被每当观测目标被改变了,让被观察者调用
void update(Observable o, Object arg);
}
public class Observable {
private boolean changed = false;
//观察者的集合
private Vector obs;
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector();
}
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
//通知所有订阅此主题的观察者对象
public void notifyObservers(Object arg) {
Object[] arrLocal;
//同步代码块
synchronized (this) {
//若主题没有改变,返回
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
//通知观察者,调用观察者的update()方法
((Observer)arrLocal[i]).update(this, arg);
}
//清空所有观察此主题的观察者
public synchronized void deleteObservers() {
obs.removeAllElements();
}
//主题改变
protected synchronized void setChanged() {
changed = true;
}
//清除改变
protected synchronized void clearChanged() {
changed = false;
}
//判断主题是否改变
public synchronized boolean hasChanged() {
R eturn changed;
}
//返回观察者的数量
public synchronized int countObservers() {
Return obs.size();
}
}
总结:观察者模式实现相对简单,但是在一些典型应用中却很实用.复杂环境可以结合其他的模式 来完成整个模块或者系统的设计.