观察者模式,简单来说,就是允许一个事物(观察者)监听、观察另一个事物(主体),当主体有事件发生时,就自动地做出相应的变化。他们之间形成一种发布/订阅(publish-subscribe)的关系。通过这种模式,观察者可以注册监听主体的事件,而当主体要通知观察者的时候,它只需要把事件发送给各个观察者。
用这种模式的好处是:它使两个有调用关系的类之间降低了耦合关系,事件的主体不需要知道任何关于观察者的信息,相应地,它只需允许观察者来订阅事件。
下面写一个例子,通过例子来加深理解。
先定义两个接口:观察者和事件的主体
public interface Observer {
public void update(Subject s);
}
public interface Subject {
public void addObserver(Observer o);
public void removeObserver(Observer o);
}
再来写个类 实现 主体的接口,一方面用来管理类,另一方面用来管理(存储数据)。本例子中,主要实现两个功能:一把一串数字相加,二把一串数字打出来。
import java.util.ArrayList;
import java.util.Iterator;
import cn.ling.observer.interfaces.Observer;
import cn.ling.observer.interfaces.Subject;
public class IntegerDataBag implements Subject{
private ArrayList<Observer> observers = new ArrayList<Observer>();
@Override
public void addObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
private ArrayList<Integer> listInt = new ArrayList<Integer>();
public void addInt(Integer i){
listInt.add(i);
//注意,加入一个整数时就要通知一下观察者,这步很关键
notifyObservers();
}
public Integer remove(int index){
if(index < listInt.size()){
Integer i = listInt.remove(index);
//注意,删除一个整数时也要通知一下观察者,这步很关键
notifyObservers();
return i;
}
return null;
}
public Iterator<Integer> iterator(){
return listInt.iterator();
}
public void notifyObservers(){
Iterator<Observer> it = observers.iterator();
while(it.hasNext()){
it.next().update(this);
}
}
}
再来实现观察者接口。
这些类用来处理事件的主体发出相应的动作时执行的具体过程。
首先是观察累加的事件
import java.util.Iterator;
import cn.ling.observer.interfaces.Observer;
import cn.ling.observer.interfaces.Subject;
public class IntegerAdder implements Observer {
private IntegerDataBag bag;
public IntegerAdder(IntegerDataBag bag){
this.bag = bag;
bag.addObserver(this);
}
@Override
public void update(Subject s) {
if(s == bag){
System.out.println("1内容改变了!");
int counter = 0;
Iterator<Integer> it = bag.iterator();
while(it.hasNext()){
counter += it.next();
}
System.out.println("这些数据的总和是:"+counter);
}
}
}
其次是观察打印的事件
import java.util.Iterator;
import cn.ling.observer.interfaces.Observer;
import cn.ling.observer.interfaces.Subject;
public class IntegerPrinter implements Observer {
private IntegerDataBag bag;
public IntegerPrinter(IntegerDataBag bag){
this.bag = bag;
bag.addObserver(this);
}
@Override
public void update(Subject s) {
if(s == bag){
System.out.println("2内容改变了!");
Iterator<Integer> it = bag.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
}
最后,我们写一个主类来测试一下:
public class MainTest {
/**
* @param args
*/
@SuppressWarnings("unused")
public static void main(String[] args) {
IntegerDataBag bag = new IntegerDataBag();
bag.addInt(new Integer(1));
bag.addInt(new Integer(2));
bag.addInt(new Integer(3));
bag.addInt(new Integer(4));
bag.addInt(new Integer(5));
bag.addInt(new Integer(6));
bag.addInt(new Integer(7));
bag.addInt(new Integer(8));
IntegerAdder adder = new IntegerAdder(bag);
IntegerPrinter printer = new IntegerPrinter(bag);
System.out.println("-->再加入一个新的数字");
bag.addInt(new Integer(9)); //加入时会触发观察者事件
System.out.println("");
System.out.println("-->移除一个数字");
bag.remove(0);
}
}
结果如下:
-->再加入一个新的数字 1内容改变了! 这些数据的总和是:45 2内容改变了! 1 2 3 4 5 6 7 8 9 -->移除一个数字 1内容改变了! 这些数据的总和是:44 2内容改变了! 2 3 4 5 6 7 8 9参考: http://www.javaworld.com/javaworld/javaqa/2001-05/04-qa-0525-observer.html