是什麼?java
怎麼用?設計模式
什麼狀況下用?ide
實例!函數
觀察者模式:this
一個目標對象管理全部依賴於它的觀察者對象,而且當它自己的狀態改變時主動發出通知。spa
這時候就有問題了,目標怎麼知道誰是觀察者?誰不是觀察者?並且目標要怎麼通知觀察者?設計
(我的感受兩個類通訊就能用到這東西)code
使用場景:server
今日頭條文章發佈後須要一系列的後續處理流程,好比更新這個做者建立的文章總數、將這篇文章推薦到對應的頻道、劃分文章的欄目、上報到推薦系統等等。那要其餘的這些要怎麼知道文章是否發佈呢?這時候就能夠用到觀察者模式了(事件機制)!對象
原理:
目標類須要:
一、註冊觀察者(觀察者通知目標:我要當你的觀察者)
二、移除觀察者(觀察者通知目標:我要溜了)
三、調用觀察者的提供的方法通知觀察者
觀察者須要:
一、提供目標通知觀察者時用到的方法
二、在構造函數中調用目標的註冊方法將本身註冊成目標的觀察者
例子:
氣象檢測例子:
如圖,氣象站是獲取實際氣象數據的物理設備,WeatherData對象是用來追蹤氣象站的數據,並更新佈告板。
擴充WeatherData對象,使得佈告板可以及時更新,並利於之後的擴展。
Subject 是抽象目標,全部的目標都繼承這個抽象類,這個抽象類提供了三個最基本的註冊、移除、通知觀察者的方法!
WeatherData 是具體目標,繼承自抽象目標Subject,這個類的notifyObserver經過調用觀察者的udpate方法通知觀察者狀態變化!
Observer 是抽象觀察者,全部的觀察者都繼承這個抽象類,這個抽象類提供了udpate方法,以便目標調用。
CurrentConditionDisplay、StatisticsDisplay 是具體觀察者,在這兩個類的構造方法中實現了「註冊爲目標的觀察者」!
<Head First 設計模式> code:
package Observer; public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObserver(); }
package Observer; import java.util.ArrayList; public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList(); } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } public void notifyObserver() { for (int i =0; i< observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
package Observer; public interface Observer { public void update(float temp, float humidity, float pressure); }
package Observer; public class CurrentConditionsDisplay implements Observer { private float temperature; private float humidity; private float pressure; private Subject weatherDay; public CurrentConditionsDisplay(Subject subject) { this.weatherDay = subject; weatherDay.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; display(); } public void display() { System.out.println("temp = " + temperature + " humi = " + humidity + " press = " + pressure); } }
package com.company; import Observer.CurrentConditionsDisplay; import Observer.WeatherData; public class Main { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(1, 3, 4); } }
結果:
temp = 1.0 humi = 3.0 press = 4.0