某一个事件的发生需要通知多个组件的时候。 注意这里是“多个”,如果是单个组件完全可以使用回调的方式。

JDK已经帮我们定义好了观察者模式的接口(java.util.Observale;java.util.Observer),我们如果项目中需要使用观察者模式,只需简单继承一下就可以了,JDK保证了线程安全。

Observable对象维护了一个ArrayList<监听者>,通过回调通知订阅者。 主要方法:notifyObservers,addObserver

Observer 对象需要实现的方法 update(),供Observable回调使用。

java.util.Observale源码:

for(Observer observer ;  ObserverList){
 public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

下面的一个例子是,出版社出版了一个杂志,要读者主动订阅。

发布者

public class Publisher extends Observable{


	private String magazineName;
	public String getMagazineName() {
		return magazineName;
	}
	public void setMagazineName(String magazineName) {
		this.magazineName = magazineName;
	}
	public void publish (String magazineName){
		this.magazineName = magazineName;

		this.setChanged();
		this.notifyObservers(this);

	}

}

订阅者

public class Reader implements Observer {

    @Override
    public void update(Observable arg0, Object arg1) {

        if(arg0 instanceof Publisher){

            Publisher publisher = (Publisher)arg0;
            System.out.println("有新杂志。我要订阅"+publisher.getMagazineName());
        }
    }

}  
public class TestCase {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Publisher publisher  = new Publisher();

        Reader  zhangsan = new Reader();
        publisher.addObserver(zhangsan);

        Reader  lisi = new Reader();
        publisher.addObserver(lisi);

        publisher.publish("程序员第0321期");
        //结果
        //有新杂志。我要订阅 程序员第0321期
    }
}
 

Android ContentService 的观察者模式

public interface ContentObserver {
    public void onChange(boolean stateNow);

} 

定义观察者

public class Activity implements ContentObserver{
    @Override
    public void onChange(boolean stateNow) {
    }
}  
import java.util.ArrayList;


public class Context {
    private ArrayList<ContentObserver> observerList = new  ArrayList<ContentObserver>();
    public final void registerContentObserver(ContentObserver  observer){
        observerList.add(observer);
    }
    public final void UnregisterContentObserver(ContentObserver  observer){
        observerList.remove(observer);
    }
    public void notifyChange(boolean state) {
        for(ContentObserver observer : observerList){
            observer.onChange(state);
        }
    }
}  
public static void main(String[] args) {
       Activity a1 = new Activity1();
       Activity a2 = new Activity2();

        //context是被观察者
       Context context = new Context();
       context.registerContentObserver(a1);
       context.registerContentObserver(a2);

       context.notifyChange(false);
}

上述代码的问题是没有注意线程安全问题,Context中的registerContentObserver、UnregisterContentObserver应该加上Synchronized进行线程同步控制。

06-01 14:18