目錄
概述
觀察者模式類圖
需要注意的東西
從主題推(push)和拉(push)數據
/*
@param sub 主題,爲了讓觀察者知道是哪一個主題通知它的
@param arg 通知的內容,是notifyObservers()傳入的數據對象
/*
public void update(Subject sub,Object arg){……}
//從主題推數據
/*
@param arg 通知的內容
*/
public void notifyObservers(Object arg){
```
foreach(observe:Observers){
```
observer.update(this,arg);
```
}
```
}
//從主題拉數據
setChanged(){
changed = true;
}
public void notifyObservers(Object arg){
```
if(changed){
// notify 只會在changed == true的時候通知觀察者
foreach(observe:Observers){
```
observer.update(this,arg);
```
}
chaned=false;
}
```
}
事實上在我看來推數據和拉數據最大的區別拉數據讓觀察者可以擁有從主題處選擇數據的權利,而推數據,則不考慮觀察者是否需要,一味地推送信息。
應用場景
場景說明
類圖設計
代碼實現
package observer.api;
/**
* <p>ClassName Subject
* <p>Description
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 21:56
*/
public interface Subject {
/**
* 註冊觀察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除觀察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知觀察者
*/
public void notifyObservers();
}
package observer.api;
/**
* <p>ClassName Observer
* <p>Description 觀察者
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 21:57
*/
public interface Observer {
/**
* 主題用以更新觀察者
* @param temperature
* @param humidity
* @param pressure
*/
public void update(float temperature,float humidity ,float pressure);
}
package observer.api;
/**
* <p>ClassName DisplayElement
* <p>Description
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 21:59
*/
public interface DisplayElement {
//佈告板顯示
public void display();
}
package observer.impl;
import observer.api.Observer;
import observer.api.Subject;
import java.util.ArrayList;
import java.util.Iterator;
/**
* <p>ClassName WeatherData
* <p>Description
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 22:06
*/
public class WeatherData implements Subject {
private ArrayList<Observer> observerList;
private float temperature; //溫度
private float humidity; //溼度
private float pressure; //氣壓
public WeatherData() {
this.observerList = new ArrayList<Observer>();
}
public void registerObserver(Observer observer) {
observerList.add( observer );
}
public void removeObserver(Observer observer) {
int index = observerList.indexOf( observer );
if (index >= 0) {
observerList.remove( index );
}
}
public void notifyObservers() {
Iterator<Observer> iterator = observerList.iterator();
while (iterator.hasNext()) {
iterator.next().update( temperature, humidity, pressure );
}
}
/**
* 得到更新值之後,通知觀察者
*/
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
package observer.impl;
import observer.api.DisplayElement;
import observer.api.Observer;
import observer.api.Subject;
/**
* <p>ClassName CurrentConditionsDisplay
* <p>Description 採用推的方式更新數據
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 22:08
*/
public class CurrentConditionsDisplay implements DisplayElement, Observer {
private float temperature; //溫度
private float humidity; //溼度
private float pressure; //氣壓
private Subject subject ; //當前通知的主題
public CurrentConditionsDisplay(Subject subject) {
this.subject = subject;
}
public void update(float temperature, float humidity, float pressure) {
if (subject instanceof WeatherData) {
// 如果是當前主題是WeatherData,纔會更新佈告板
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
public void display() {
System.out.println(
"天氣信息更新啦!!!" +
"temperature=" + temperature +
", humidity=" + humidity +
", pressure=" + pressure );
}
}
import observer.impl.CurrentConditionsDisplay;
import observer.impl.WeatherData;
/**
* <p>ClassName TestObserver
* <p>Description 測試
* <p>Author ChongLou
* <p>Version
* <p>Date 2017/7/12 22:21
*/
public class TestObserver {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentConditionsDisplay1 = new CurrentConditionsDisplay( weatherData );
CurrentConditionsDisplay currentConditionsDisplay2 = new CurrentConditionsDisplay( weatherData );
weatherData.registerObserver( currentConditionsDisplay1 );
weatherData.setMeasurements( 1.1f,1.2f,1.3f );
weatherData.registerObserver( currentConditionsDisplay2 );
weatherData.setMeasurements( 2.1f,2.2f,3.3f );
weatherData.removeObserver( currentConditionsDisplay1 );
weatherData.setMeasurements( 3.1f,3.2f,3.3f );
}
}
運行結果
總結