title: 觀察者模式
date: 2016-07-19 23:15:36
tags: 編程
categories: 設計模式
定義
觀察者模式是軟件設計模式的一種。在此種模式中,一個目標對象管理所有相依于它的觀察者對象唤衫,并且在它本身的狀態(tài)改變時主動發(fā)出通知祖乳。這通常透過呼叫各觀察者所提供的方法來實現(xiàn)嘁字。此種模式通常被用來實時事件處理系統(tǒng)码倦。
觀察者模式的作用
1.當抽象個體有兩個互相依賴的層面時咽块。封裝這些層面在單獨的對象內將可允許程序員單獨地去變更與重復使用這些對象忽洛,而不會產生兩者之間交互的問題腻惠。
2.當其中一個對象的變更會影響其他對象,卻又不知道多少對象必須被同時變更時欲虚。
3.當對象應該有能力通知其他對象集灌,又不應該知道其他對象的實做細節(jié)時。
在mvc上的應用
觀察者模式通常與 MVC 范式有關系复哆。在 MVC 中欣喧,觀察者模式被用來降低 model 與 view 的耦合程度。一般而言梯找, model 的改變會觸發(fā)通知其他身為觀察者的 model 唆阿。而這些 model 實際上是 view
觀察者的時序圖
抽象主題(Subject):它把所有觀察者對象的引用保存到一個聚集里,每個主題都可以有任何數(shù)量的觀察者锈锤。抽象主題提供一個接口驯鳖,可以增加和刪除觀察者對象。
具體主題(ConcreteSubject):將有關狀態(tài)存入具體觀察者對象久免;在具體主題內部狀態(tài)改變時浅辙,給所有登記過的觀察者發(fā)出通知。
抽象觀察者(Observer):為所有的具體觀察者定義一個接口阎姥,在得到主題通知時更新自己记舆。 具體觀察者(ConcreteObserver):實現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題狀態(tài)協(xié)調呼巴。
實現(xiàn)
全局掌握
在氣象觀測站中泽腮,它能夠追蹤目前的天氣狀況,包括溫度衣赶、適度诊赊、氣壓。需要實現(xiàn)一個布告板屑埋,能夠分別顯示目前的狀態(tài)豪筝,氣象統(tǒng)計和簡單的預報痰滋。當氣象站中獲取最新的測量數(shù)據(jù)時摘能,三種布告板必須實時更新续崖。當然可以直接擴展布告板,不過首先要向主題注冊团搞,才能夠在主題更新的時候更新布告板的信息严望,分析圖如下:
就像現(xiàn)在非常流行的rss訂閱,當你訂閱的時候逻恐,主題者會把你的注冊信息添加像吻,當主題要發(fā)布新的信息的時候,你接受到的更新會更新你自己的觀察者的信息复隆,呈現(xiàn)給閱讀者看
觀察者模式解決了主題更新拨匆,觀察者就要修改源代碼的麻煩,降低了耦合度挽拂,實現(xiàn)了抽象和實體的分離惭每,為三層架構提供了可能。
代碼實現(xiàn)
代碼接口
---Java
public interface Subject {
/**
* 注冊觀察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 刪除觀察者
* @param observer
*/
public void removeOberver(Observer observer);
/**
* 當主題狀態(tài)發(fā)生改變時亏栈,這個方法需要被調用台腥,以通知所有觀察者
*/
public void notifyObserver();
}
觀察者接口
---java
public interface Observer {
public void update(float temp,float humidity,float pressure);
}
public interface DisplayElement {
public void display();
}
主題實現(xiàn)
public class WeatherData implements Subject{
private List<Observer> observers;
private float tempterature;
private float pressure;
private float humidity;
public WeatherData(){
observers = new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
for(int i = 0; i < observers.size();i++){
Observer observer = observers.get(i);
observer.update(tempterature, humidity, pressure);
}
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeOberver(Observer observer) {
int i = observers.indexOf(observer);
if(i >= 0){
observers.remove(i);
}
}
/**
* 氣象站得到更新的觀測數(shù)據(jù)時,通知觀察者
*/
public void measurementChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.tempterature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
}
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this); //注冊觀察者
}
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity");
}
}
測試類
package weatherDataTest;
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData=new WeatherData();
CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.5f);
weatherData.setMeasurements(83, 55, 29.7f);
weatherData.setMeasurements(78 , 90, 34.2f);
}
}
/*
總結:
觀察者模式是設計一個程序的一個很重要的模式绒北,實現(xiàn)了實體和邏輯的分離黎侈,在控制中就能夠控制view層的活動,可以更加靈活的 去開發(fā)軟件闷游,讓自己有更多的時間去關注于軟件的業(yè)務功能峻汉,提高了開發(fā)效率
本文的例子來自《head first 設計模式》