觀察者模式

 

某一個事件的發生須要通知多個組件的時候。 注意這裏是「多個」,若是是單個組件徹底可使用回調的方式。java

JDK已經幫咱們定義好了觀察者模式的接口(java.util.Observale;java.util.Observer),咱們若是項目中須要使用觀察者模式,只需簡單繼承一下就能夠了,JDK保證了線程安全。程序員

Observable對象維護了一個ArrayList<監聽者>,經過回調通知訂閱者。 主要方法:notifyObservers,addObserver安全

Observer 對象須要實現的方法 update(),供Observable回調使用。ide

java.util.Observale源碼:this

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);
    }

 

下面的一個例子是,出版社出版了一個雜誌,要讀者主動訂閱。spa

發佈者線程

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);
		
	}

}

 

訂閱者code

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);  
  
}

定義觀察者server

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進行線程同步控制。對象

相關文章
相關標籤/搜索