Java設計模式二-觀察者模式

編程語言 Java 設計模式 技術 池塘的泥鰍 2017-06-22

Java設計模式二-觀察者模式

定義

定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。

設計原則

為了交互對象之間的鬆耦合設計而努力(鬆耦合的設計之所以能讓我們建立有彈性的OO系統,能夠應對變化,是因為對象之間的互相依賴降到了最低)。

實例

氣象監測應用,氣象站數據更新後更新佈告板的數據(溫度、溼度、氣壓),佈告板根據自己的需求顯示,佈告板的數量和種類可動態增加。

實現

有兩種實現方式,一種是氣象站(主題)主動推送的方式,另一種是佈告板(觀察者)主動獲取的方式。主動推送的方式只需要觀察者實現指定接口,並且註冊到主題,觀察者就能收到推送內容,這樣能隨意的增加觀察者,但難免觀察者會收到一些垃圾數據。觀察者主動獲取的方式雖然能按需獲取數據,但主題的數據暴露出來會不太安全。兩種方式各有優缺點,我們按實際情況選擇,下面實現的是氣象站主動推送的方式:

1. 新建被觀察者(主題)接口

public interface Subject {

public void registerObserver(Observer o); //註冊觀察者

public void removeObserver(Observer o); //移除觀察者

public void notifyObservers(); //通知觀察者

}

2. 氣象站實現類

public class WeatherData implements Subject {

private ArrayList<Observer> observerlist;//觀察者列表

private float temperature;//溫度

private float humidity;//溼度

private float pressure;//qiya

public WeatherData(){

observerlist = new ArrayList<>();

}

public void registerObserver(Observer o) {//註冊觀察者

observerlist.add(o);

}

public void removeObserver(Observer o) {//移除觀察者

int i = observerlist.indexOf(o);

if(i>0){

observerlist.remove(o);

}

}

public void notifyObservers() {//通知觀察者更新數據

observerlist.stream().forEach(v->v.update(temperature, humidity, pressure));

}

public void setMeasurements(float temperature, float humidity, float pressure){//數據更新

this.temperature = temperature;

this.humidity = humidity;

this.pressure = pressure;

measurementsChanged();

}

public float getTemperature() {//獲取溫度

return temperature;

}

public float getHumidity() {//獲取溼度

return humidity;

}

public float getPressure() {//獲取氣壓

return pressure;

}

public void measurementsChanged(){

notifyObservers();

}

}

3. 新建觀察者接口

public interface Observer {//觀察者數據更新,供被觀察者調用

public void update(float temp, float humidity, float pressure);

}

public interface DisplayElement {//觀察者diy顯示

public void display();

}

4. 創建佈告板

public class CurrentConditionsDisplay implements DisplayElement,Observer {

private float temperature;

private float humidity;

private float pressure;

private WeatherData weatherData;

public CurrentConditionsDisplay(WeatherData weatherData) {

this.weatherData = weatherData;//拿到氣象站對象

weatherData.registerObserver(this);//註冊當前的佈告板

}

@Override

public void update(float temp, float humidity, float pressure) {//數據更新

this.temperature = temp;

this.humidity = humidity;

this.pressure = pressure;

display();

}

@Override

public void display() {//diy顯示

System.out.println("current conditions: " +temperature+"F degrees and "+ humidity+"% humidity and "+pressure+ "bps");

}

}

5.測試

public class Test {

public static void main(String[] args) {

WeatherData weatherData = new WeatherData();//註冊主題

//新建觀察者

CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);

weatherData.setMeasurements(1f,2f,3f);

}

}

輸出:

current conditions: 1.0F degrees and 2.0% humidity and 3.0bps

Java設計模式二-觀察者模式

總結

從實例看出,氣象站是被觀察者,佈告板是觀察者,我們找出需求中變化的部分(佈告板),然後將其和固定不變的的方面(氣象站)相分離,這樣很好地實現了鬆耦合,可以動態增加布告板。以上實例自主實現觀察者模式,其實jdk中內置了該模式,我們也可以直接使用,這裡就不一一實現,但原理都是一樣的。

相關推薦

推薦中...