1. 程式人生 > >設計模式之觀察者-Java(簡單例子)

設計模式之觀察者-Java(簡單例子)

1、定義:源於GOF的Design Patterns一書。

Define a one-to-many dependency between objects so that when oneobject changes

state, all its dependents are notified and updatedautomatically.

大概的意思就是說:一對多的物件之間,當一個物件的資料/狀態發生變化時,所有與之關聯的物件都會得到通知,並自動更新。(筆者英文不好)

2、為什麼要使用觀察者模式?

下面舉個例子。全國各個地方的氣象臺,他們都是根據國家氣象監測局監測到的氣象資訊資料進行播報。

這是個簡單的例子,監測局是一個具體的主題,各個地方氣象臺充當著各個具體的觀察者,他們要根據監測局的資訊變化來進行實時的氣象釋出,播報。也就是說,監測局得到資訊發生改變,各個地方的氣象臺就得得到通知並作出響應。

下面我們來看一下具體的類圖

 

主題<介面>:規定了具體主題需要實現的方法,管理觀察者以及通知觀察者的方法

觀察者<介面>:規定了具體觀察者需要實現的方法,收到通知作出響應的方法

監測局<具體實現類>:實現具體管理和通知邏輯

氣象臺<具體實現類>:實現收到通知的具體響應操作

3、簡單程式碼實現

/*
 * 主題介面
 */
public interface Subject {

	void addObserver(Observer o);
	void delectObserver(Observer o);
	void notifyObserver();
	
	//拉資料的是形式獲取資料
	String getData();

}
/*
 * 觀察者介面
 */
public interface Observer {
	
	void update();
	

}
import java.util.ArrayList;
import java.util.List;
/*
 * 監測局
 */
public class Monitor implements Subject{

	//觀察者list
	List<Observer> observerList;
	
	//監測到的氣象資訊
	String weatherData;

	public Monitor() {
		observerList = new ArrayList<Observer>();
		weatherData = "";
	}
	
	/*
	 * 增加觀察者
	 */
	public void addObserver(Observer o) {
		if(!observerList.contains(o)){
			observerList.add(o);
		}
	}

	/*
	 * 移除觀察者
	 */
	public void delectObserver(Observer o) {
		if(observerList.contains(o)) {
			observerList.remove(o);
		}
	}

	/*
	 * 通知觀察者更新資料
	 */
	public void notifyObserver() {
		for (int i = 0; i < observerList.size(); i++) {
			Observer o = observerList.get(i);
			o.update();
		}
	}

	/*
	 * 監測的方法(簡單舉例子,實際肯定沒這麼簡單)
	 */
	public void setWeatherData(String data) {
		weatherData = data;
		notifyObserver();
	}
	
	/*
	 * 獲取資料
	 */
	public String getData() {
		return weatherData;
	}	
}
/*
 * 氣象臺1
 */
public class Observatory1 implements Observer{

	String name;
	Subject subject;
	
	public Observatory1(String name, Subject subject) {
		this.name = name;
		this.subject = subject;
		
		subject.addObserver(this);
	}
	
	public void update() {
		System.out.println("大家好,我是"+name+",今天天氣:"+subject.getData());
	}
}
/*
 * 氣象臺2
 */
public class Observatory2 implements Observer{

	String name;
	Subject subject;
	
	public Observatory2(String name, Subject subject) {
		this.name = name;
		this.subject = subject;
		
		subject.addObserver(this);
	}
	
	public void update() {
		System.out.println("大家好,我是"+name+",今天天氣:"+subject.getData());
	}

}
public class Main {


	public static void main(String[] args) {
		//監測局例項
		Monitor monitor = new Monitor();
		//氣象局例項
		Observatory1 o1 = new Observatory1("廣州臺", monitor);
		Observatory2 o2 = new Observatory2("深圳臺", monitor);
		
		//監測局監測天氣
		monitor.setWeatherData("晴天");
	}

}

 

執行結果:

 

4、觀察者模式獲取資料的兩種方式

     ⑴、推資料,也具體主題就是在通知的時候將資料引數形式傳到具體觀察者中,觀察者再進行處理

    ⑵、拉資料,具體主題提供相關的資料獲取方法,可以是部分的,也可以是整體的,具體觀察者收到通知後,在響應操作中呼叫具體主題提供的方法獲取資料(舉栗子:上述的例子中,氣象臺1只關心天氣狀況,氣象臺2只關心氣溫變化,監測局就必須提供返回不同資料的多個方法,供具體氣象臺呼叫)

 

5、上面的例子寫得比較簡單,只是供理解觀察者設計模式的思想,並不是說什麼程式設計,當然筆者也是個菜鳥~

    實際程式設計當中很少會使用上面那種自定義的主題和觀察者,而是使用Java util類庫提供了Obserable類和Observer介面。這樣有什麼優點呢,筆者認為這是有利於系統複用。

相關的請轉查Java官方Api。

 

6、文章寫得簡單粗暴,算是學習筆記,僅供入門學習參考。(深入等筆者日後再續)