一、 观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。当这个主题对象发生变化时,会通知所有观察者对象,让它们能够自动更新自己。
二、观察者模式的组成
抽象主题角色:把所有观察者的引用保存到一个集合中,每个抽象主题角色都可
有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者,一般用一个
抽象类和接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题通知时更新自己。
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知,具体主题角色通常用一个子类来实现。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现,如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
三、观察者模式的工作原理:
创建监听器对象(即具体观察者对象),然后把监听器对象添加到事件源(即具体主题角色),当事件源发生变化时触发事件(即具体主题角色状态改变,同志观察者)!
下面举例说明:
抽象观察者:
public interface Observer {
public void updae(Subject s);
}
具体观察者:
/**
* 具体观察者角色,实现抽象观察者角色接口
* Created by Administrator on 2015/12/25.
*/
public class ConcreteWatcher implements Watcher {
private String watcherName;//具体观察者名字
public ConcreteWatcher(String watcherName){
this.watcherName = watcherName;
}
@Override
public void update(String str) {
System.out.println(this.watcherName+"got the notified:"+str);
}
}
抽象主题:
/**
* 抽象主题角色,被观察对象
* Created by Administrator on 2015/12/25.
*/
public interface Watched {
public void register(Watcher watcher);//注册观察者
public void remove(Watcher watcher);//删除观察者
public void notifyAllWatchers(String str);//通知观察者
}
具体主题:
import watch_mode.Observer;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2015/12/25.
*/
public class ConcreteWatched implements Watched {
private List<Watcher> watcherList = new ArrayList<Watcher>();
@Override
public void register(Watcher watcher) {
watcherList.add(watcher);
}
@Override
public void remove(Watcher watcher) {
watcherList.remove(watcher);
}
@Override
public void notifyAllWatchers(String str) {
for (Watcher watcher : watcherList){
watcher.update(str);
}
}
}
测试类:
/**
* Created by Administrator on 2015/12/25.
*/
public class Test {
public static void main(String[] args) {
Watched watched = new ConcreteWatched();
watched.register(new ConcreteWatcher("Hebe"));
watched.register(new ConcreteWatcher("Sylina"));
watched.register(new ConcreteWatcher("Ella"));
watched.notifyAllWatchers("下周五连续三天元旦放假!");
}
}
五、java中的观察者模式
java中的内置观察者模式有两个类:一个是observable被观察者类,一个是observer观察者接口。大体上与自定义模式相同,我们编写程序时只需继承obervable类,具体实现observer接口就可以了。
需要注意的是:调用notifyObservers()方法之前,必须先调用setChanged()方法。这是因为observable类中把changed变量初始化为false,notifyObservers()方法会先检查该变量是否为true,如果不为ture,就不会调用update()方法,这就要我们调用notifyObservers()之前,先用setChanged()方法将changed变量设置为true。
代码如下:
实现自带Observer接口
package com.model.observer.java;
import java.util.Observable;
import java.util.Observer;
/**
* java自带的观察者模式中抽象观察者Observer
* Created by Administrator on 2016/3/2.
*/
public class Watcher implements Observer {
private String name;
public Watcher(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(this.name + "接到通知:" + arg);
}
}
继承被观察者对象的实现类:
package com.model.observer.java;
import java.util.Observable;
import java.util.Observer;
/**
* java自带的已实现观察者模式中抽象被观察者Observable
* Created by Administrator on 2016/3/2.
*/
public class Subject extends Observable {
//测试程序入口
public static void main(String[] args) {
Subject s = new Subject();//创建被观察者对象
Observer observer = new Watcher("Sara");//创建观察者对象,可以多个
s.addObserver(observer);//注册观察者
s.setChanged();//被观察者状态发生变化,change设置为true
s.notifyObservers("发工资啦!");//通知观察者
}
}