本篇文章大部分摘錄自 http://c.biancheng.net/view/1390.htmlhtml
在現實世界中,許多對象並非獨立存在的,其中一個對象的行爲發生改變可能會致使一個或者多個其餘對象的行爲也發生改變。例如,某種商品的物價上漲時會致使部分商家高興,而消費者傷心;還有,當咱們開車到交叉路口時,遇到紅燈會停,遇到綠燈會行。這樣的例子還有不少,例如,股票價格與股民、微信公衆號與微信用戶、氣象局的天氣預報與聽衆、小偷與警察等。java
在軟件世界也是這樣,例如,Excel 中的數據與折線圖、餅狀圖、柱狀圖之間的關係;MVC 模式中的模型與視圖的關係;事件模型中的事件源與事件處理者。全部這些,若是用觀察者模式來實現就很是方便。微信
觀察者(Observer)模式的定義:指多個對象間存在一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。這種模式有時又稱做發佈-訂閱模式、模型-視圖模式,它是對象行爲型模式。ide
觀察者模式是一種對象行爲型模式,其主要優勢以下。測試
它的主要缺點以下。.net
實現觀察者模式時要注意具體目標對象和具體觀察者對象之間不能直接調用,不然將使二者之間緊密耦合起來,這違反了面向對象的設計原則。設計
觀察者模式的主要角色以下。code
觀察者模式的結構圖如圖 1 所示。server
天氣做爲該例子的主題,氣象局、媽媽還有學生都是天氣的觀察者,天氣發出提醒時,全部天氣觀察者都會作出迴應。htm
// 抽象主題 public abstract class AbstractSubject { protected List<Observer> observerList = new ArrayList<>(); public void add(Observer observer) { observerList.add(observer); } public void remove(Observer observer) { observerList.remove(observer); } public abstract void notifyObservers(String status); } // 抽象觀察者 public interface Observer { void response(String status); } // 具體主題 public class WeatherSubject extends AbstractSubject { @Override public void notifyObservers(String status) { for (Observer ob : observerList) { ob.response(status); } } } // 具體觀察者 (氣象局、媽媽、學生) public class WeatherCenterObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("氣象局:要下雨了!"); else System.out.println("氣象局:天氣晴朗!"); } } // 媽媽 public class MomObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("媽媽:下雨了!回家收衣服!"); else System.out.println("媽媽:好天氣,曬衣服!"); } } // 學生 public class StudentObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("學生黨:下雨了,出門帶傘!"); else System.out.println("學生黨:天氣好!不用帶傘出門!"); } }
測試例子
public static void main(String[] args) { AbstractSubject weatherSubject = new WeatherSubject(); weatherSubject.add(new WeatherCenterObserver()); weatherSubject.add(new MomObserver()); weatherSubject.add(new StudentObserver()); weatherSubject.notifyObservers("rain"); } // 輸出結果: // 氣象局:要下雨了! // 媽媽:下雨了!回家收衣服! // 學生黨:下雨了,出門帶傘!
我只作了一個簡單的例子便於理解觀察者模式,實際使用中,每每經過JMS和MQ來輔助實現觀察者模式,而且須要事件相關對象的傳導(使用泛型),這都是更高級的設計裏須要考慮到的。
經過前面的分析與應用實例可知觀察者模式適合如下幾種情形。
在 Java 中,經過 java.util.Observable 類和 java.util.Observer 接口定義了觀察者模式,只要實現它們的子類就能夠編寫觀察者模式實例。
Observable 類是抽象目標類,它有一個 Vector 向量,用於保存全部要通知的觀察者對象,下面來介紹它最重要的 3 個方法。
Observer 接口是抽象觀察者,它監視目標對象的變化,當目標對象發生變化時,觀察者獲得通知,並調用 void update(Observable o,Object arg) 方法,進行相應的工做。