【聲明】
歡迎轉載,但請保留文章原始出處→_→
生命壹號:http://www.cnblogs.com/smyhvae/
文章來源:http://www.cnblogs.com/smyhvae/p/3899208.html
【正文】
一、觀察者模式的定義:
簡單地說,觀察者模式定義了一個一對多的依賴關系,讓一個或多個觀察者對象監聽一個主題對象。這樣一來,當被觀察者狀態發生改變時,需要通知相應的觀察者,使這些觀察者對象能夠自動更新。例如:GUI中的事件處理機制采用的就是觀察者模式。
二、觀察者模式的實現:
- Subject(被觀察的對象接口):規定ConcreteSubject的統一接口 ; 每個Subject可以有多個Observer;
- ConcreteSubject(具體被觀察對象):維護對所有具體觀察者的引用的列表 ;–狀態發生變化時會發送通知給所有注冊的觀察者。
- Observer(觀察者接口):規定ConcreteObserver的統一接口;定義了一個update()方法,在被觀察對象狀態改變時會被調用。
- ConcreteObserver(具體觀察者):維護一個對ConcreteSubject的引用;特定狀態與ConcreteSubject同步; 實現Observer接口,update()方法的作用:一旦檢測到Subject有變動,就更新信息。
圖表描述如下:

注:在被觀察者類中需要有一個集合維護所有觀察者。
三、舉例說明:
【方案一】:自己定義接口或者類來實現觀察者模式。
步驟如下:
(1)定義被觀察者所具有的接口:
1 package com.vince.observer; 2 public interface Observable { 3 //注冊為一個觀察者 4 public void registerObserver(Observer observer); 5 6 //取消觀察者 7 public void removeObserver(Observer observer); 8 9 //通知所有觀察者更新信息 10 public void notifyObservers(); 11 }
(2)定義具體的被觀察者:杯子
1 package com.vince.observer; 2 import java.util.Vector; 3 4 public class Cup implements Observable{ 5 //被觀察者維護的一個觀察者對象列表 6 private Vector<Observer> vector = new Vector<Observer>(); 7 private float price; 8 9 public Cup(float price){ 10 this.price = price; 11 } 12 13 public float getPrice() { 14 return price; 15 } 16 public void setPrice(float price) { 17 //修改價格時,通知所有觀察者 18 this.price = price; 19 notifyObservers(); 20 } 21 @Override 22 public void registerObserver(Observer observer) { 23 //注冊觀察者 24 vector.add(observer); 25 } 26 @Override 27 public void removeObserver(Observer observer) { 28 //取消觀察者 29 vector.remove(observer); 30 } 31 @Override 32 public void notifyObservers() { 33 //實現通知所有的觀察者對象 34 for (Observer observer:vector) { 35 observer.update(price); 36 } 37 } 38 }
(3)定義觀察者所具有的共同的接口:(更新數據最終當然是在觀察者那里進行啦)
1 package com.vince.observer; 2 3 public interface Observer { 4 public void update(float price); 5 }
(4)定義具體的觀察者對象:
1 package com.vince.observer; 2 public class Person implements Observer{ 3 private String name; 4 public Person(String name){ 5 this.name = name; 6 } 7 @Override 8 public void update(float price) { 9 System.out.println(name+"關注的杯子的價格已更新為:"+price); 10 } 11 }
(5)測試:
1 package com.vince.observer; 2 public class Test { 3 public static void main(String[] args) { 4 //創建一個被觀察者對象 5 Cup doll = new Cup(3000); 6 //創建兩個觀察者對象 7 Person p1 = new Person("生命壹號"); 8 Person p2 = new Person("生命貳號"); 9 //注冊成為一個觀察者 10 doll.registerObserver(p1); 11 doll.registerObserver(p2); 12 13 System.out.println("第一輪促銷:"); 14 doll.setPrice(2698);// 價格變動 15 System.out.println("第二輪促銷:"); 16 doll.setPrice(2299);// 17 System.out.println("第三輪促銷:"); 18 doll.setPrice(1998); 19 20 doll.removeObserver(p2); //將生命二號移除 21 System.out.println("第四輪促銷:"); 22 doll.setPrice(1098); 23 24 } 25 }
運行后,顯示結果如下:

【方案二】:直接調用JDK的API去實現。
步驟如下:
(1) 通過繼承Observable類實現具體的被觀察者對象:
1 package com.vince.observer2; 2 import java.util.Observable; 3 4 public class Cup extends Observable{ 5 private float price; 6 7 public Cup(float price){ 8 this.price = price; 9 } 10 public float getPrice() { 11 return price; 12 } 13 public void setPrice(float price) { 14 this.price = price; 15 this.setChanged();//通知,數據已改變 16 this.notifyObservers(); 17 } 18 19 20 }
(2)通過實現java.util.Observer接口實現具體的觀察者對象:
1 package com.vince.observer2; 2 import java.util.Observable; 3 import java.util.Observer; 4 5 public class Person implements Observer{ 6 private String name; 7 public Person(String name){ 8 this.name = name; 9 } 10 @Override 11 public void update(Observable o, Object arg) { 12 if(o instanceof Cup){ 13 Cup cup = (Cup)o; 14 System.out.println(name+"關注的杯子價格已更新為:"+cup.getPrice()); 15 } 16 } 17 }
(3)測試:
1 package com.vince.observer2; 2 public class Test { 3 public static void main(String[] args) { 4 Cup cup = new Cup(3000); 5 Person p1 = new Person("生命壹號"); 6 Person p2 = new Person("生命貳號"); 7 cup.addObserver(p1); 8 cup.addObserver(p2); 9 System.out.println("第一輪促銷"); 10 cup.setPrice(2988); 11 System.out.println("第二輪促銷"); 12 cup.setPrice(2698); 13 14 cup.deleteObserver(p2); 15 System.out.println("第三輪促銷"); 16 cup.setPrice(1998); 17 } 18 }
運行后,結果如下:

【工程文件】
鏈接:http://pan.baidu.com/s/1c03rLFM
密碼:hois
四、總結:(觀察者模式的作用)
- 觀察者模式在被觀察者和觀察者之間建立一個抽象的耦合。被觀察者角色所知道的只是一個具體觀察者列表。
由於被觀察者和觀察者沒有緊密地耦合在一起,因此它們可以屬於不同的抽象化層次。如果被觀察者和觀察者都被扔到一起,那么這個對象必然跨越抽象化和具體化層次。
- 觀察者模式支持廣播通訊。被觀察者會向所有的登記過的觀察者發出通知。
推薦學習鏈接:http://blog.csdn.net/crave_shy/article/details/21235855
我的公眾號
想學習代碼之外的軟技能?不妨關注我的微信公眾號:生命團隊(id:vitateam)。
掃一掃,你將發現另一個全新的世界,而這將是一場美麗的意外:

