史上最易懂的觀察者和被觀察者模式——Java自帶Observer,Observable類講解

這幾天review公司的代碼,在查資料的過程中發現Java SDK中竟然自帶了Observer和Observable類,有點出乎我意料。下班之後帶着好奇的心態,使用了一下,竟然發現還挺好用。在這裏也寫一篇博客來記錄一下整個實踐過程。

爲了便於理解,先來講個出版社和讀者的故事吧:很久很久以前,有一家備受歡迎的出版社和一羣忠實的讀者,每次出版社的新書出版,讀者們都會收到來信。後來,互聯網時代到了,爲了更好的服務讀者,出版社編寫了一套系統,每次新書發佈,這套系統都會自動地給讀者分發圖書,讀者朋友在收到書之後也都會向出版社報告。

那麼這套系統是怎麼實現的呢,我們來拆分一下需求:

首先是出版社,作爲分發的主體,由於時刻被讀者朋友們盯着,肯定是被觀察者了,整個分發過程中作爲信息源頭,負責將圖書信息分發給讀者。

其次是讀者朋友,作爲接受信息的主體,時刻觀察着出版社的動向,只要出版社新書發佈,馬上就會收到消息,並且還會給出版社一個收到圖書的報告。在這裏,把他們作爲觀察者Observer。

好了,故事講完了,下面開始扒了猛幹。

Talk is cheap,show me the code.先來貼個小代碼

public class Reader implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		System.out.println("Observable:" +o.getClass()+ "get:" + arg.toString());
	}

}

這裏的Observer就是Java原生的接口了,我們在使用的時候只需要實現裏面的update方法即可,當數據更新的時候會由Observable類內部持有的對象進行回調,整個過程完全自動化。

下面再來看一下出版社吧

public class Publisher extends Observable {
	
	public void setData(){
		this.setChanged();
	}
	
	
}

這裏的Publisher繼承了Observable類,通過觀察源碼我們不難發現,Observable中的setData是Protect修飾的,也就是說我們在SDK包的外部無法進行訪問,爲了能夠使用這個改變通知數據的功能,我們在這裏Override了setData方法,並且調用了setChanged方法來來改變相應的數據開關,至於什麼是數據開關,大家先不用關心,在通知數據改變的過程中會交由父方法進行檢查。

好了,現在基礎類寫好了,讓我們的系統跑起來

public class ObserverTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Publisher publisher = new Publisher();
		Reader reader1 = new Reader();
		Reader reader2 = new Reader();
		publisher.addObserver(reader1);
		publisher.addObserver(reader2);
		publisher.setData();
		publisher.notifyObservers("收到圖書");
		System.out.println("ObserverCount:" + publisher.countObservers());
	}
}

在上面的代碼中我們一共做了以下幾件事:

  1. 創建了一個出版社對象
  2. 找來了兩名熱心讀者
  3. 把熱心讀者加入了出版社關懷,以便在出版社發出消息的時候這兩名讀者能夠收到消息
  4. 出版社馬上有了動作,新書出版了,出版社扳動了消息開關,準備推送消息。
  5. 出版社做出了具體的消息推送動作:告訴讀者,如果你們收到消息,就告訴我一下:收到圖書
  6. 最後出版社統計了一下讀者人數。

讓我們來看一下最後到底發生了什麼吧:

Observable:class observerTest.Publisherget:收到圖書
Observable:class observerTest.Publisherget:收到圖書
ObserverCount:2

看,讀者們收到了圖書,並且向出版社做出了迴應,一次完美的圖書發佈過程就此完畢。

到了這裏,故事也就講完了。投過故事,我們回頭來想一下,這個故事的本質是什麼?

可能就是觀察者和被觀察者設計模式吧,也就是我們俗稱的回調。

以我所見,觀察者和被觀察者設計模式最核心的動作可能就是觀察者的註冊動作了,在這個故事中也就是出版商將讀者加入關懷的動作。少了這個動作,可能任何人都沒辦法將二者聯繫起來,更別提什麼回調了。

好了,故事講完了,你明白這種設計模式了嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章