深入JDK源代碼之Observer接口和Observable類實現觀察者模式

[color=red][b]一、何爲觀察者模式?[/b][/color]
觀察者模式(有時又被稱爲發佈/訂閱模式)是軟體設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實作事件處理系統。
[color=red][b]二、使用它它有何好處?[/b][/color]
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,用戶界面可以作爲一個觀察者,業務數據是被觀察者,用戶界面觀察業務數據的變化,發現數據變化後,就顯示在界面上。面向對象設計的一個原則是:系統中的每個類將重點放在某一個功能上,而不是其他方面。一個對象只做一件事情,並且將他做好。觀察者模式在模塊之間劃定了清晰的界限,提高了應用程序的可維護性和重用性。
[color=red][b]三、實現方式[/b][/color]
 觀察者模式有很多實現方式,從根本上說,該模式必須包含兩個角色:觀察者和被觀察對象。在剛纔的例子中,業務數據是被觀察對象,用戶界面是觀察者。觀察者和被觀察者之間存在“觀察”的邏輯關聯,當被觀察者發生改變的時候,觀察者就會觀察到這樣的變化,並且做出相應的響應。如果在用戶界面、業務數據之間使用這樣的觀察過程,可以確保界面和數據之間劃清界限,假定應用程序的需求發生變化,需要修改界面的表現,只需要重新構建一個用戶界面,業務數據不需要發生變化。
[color=red][b]四、JDK中的Observer接口和Observable類實現[/b][/color]
1.在Observer接口源代碼中只聲明一個update()方法
public interface Observer {
//這個方法被每當觀測目標被改變了,讓被觀察者調用
void update(Observable o, Object arg);
},這個
方法讓被觀察者的對象當改變時調用這個方法。實現這個接口的類,可以作爲觀察者。
2.Observable類,被觀察者,消息的發出者,繼承此類可以擴展。

package java.util;
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() {
return changed;
}

//返回觀察者的數量
public synchronized int countObservers() {
return obs.size();
}
}

[color=red][b]五、觀察者模式Demo實例[/b][/color]
package com.zzs.tet;

import java.util.* ;
class TieDaoBu extends Observable{ // 表示鐵道部可以被觀察
private String message;// 官方消息
public TieDaoBu(String message){
this.message = message ;
}
public String getMessagee(){
return this.message ;
}
public void setMessgae(String message){
// 每一次修改的時候都應該引起觀察者的注意
System.out.println("****************************************");
System.out.println( new Date()+"官方發佈消息爲:" + message);
super.setChanged() ; // 設置變化點
super.notifyObservers(message) ;// 通知所有觀察者
this.message = message ;
}
};
class TieDaoBuObserver implements Observer{
private String name ;
public TieDaoBuObserver(String name){ // 設置每一個觀察者的名字
this.name = name ;
}
public void update(Observable o,Object arg){
System.out.print(this.name + " 官方消息更改爲:") ;
System.out.println(arg.toString()) ;
}
};
public class ObserDemo01{
public static void main(String args[]){
TieDaoBu h = new TieDaoBu("溫州火車出軌體現了我國高鐵世界技術水平領先,和諧社會和諧號出事了") ;
TieDaoBuObserver hpo1 = new TieDaoBuObserver("媒體A") ;
TieDaoBuObserver hpo2 = new TieDaoBuObserver("屁民B") ;
TieDaoBuObserver hpo3 = new TieDaoBuObserver("日本韓國嘲笑者C") ;
h.addObserver(hpo1) ;
h.addObserver(hpo2) ;
h.addObserver(hpo3) ;

h.setMessgae("搜救結束,經生命探測儀發現沒有生命跡象") ; // 修改官方消息

h.setMessgae("搜救結束了,還發現了一名2歲的女孩,真是奇蹟") ; // 修改官方消息

h.setMessgae("35一個神奇的數字,動車相撞35人死亡,河南平頂山礦難35人死亡," +
"重慶暴雨35人死亡,雲南大雨35人死亡。" +
"爲什麼死亡人數控制在36人以內?" +
"超過36人市委書記級別的要撤職,所以一開始發生就註定了死亡人數不會超過36。" +
"而事實上,我在查看國外報紙報道," +
"華爾街日報說,這次動車事故,其中有47人死亡,200餘人受傷") ; // 修改官方消息
}
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章