觀察者模式主要用於 1 :N 的通知。當一個對象(目標對象 Subject 或 Observable)的狀態變化時,它須要通知一系列對象(觀察者對象 Observer),令它們作出響應。java
通知觀察者的方式:服務器
(1)推網絡
每次都會把通知以廣播的方式發送給全部觀察者,全部觀察者只能被動接收。ide
(2)拉測試
觀察者只要知道有狀況便可。至於何時獲取內容,獲取哪些內容,均可以自主決定。this
1 /** 2 * 觀察者對象接口 3 * @author CL 4 * 5 */ 6 public interface Observer { 7 /** 8 * 更新主題 9 * @param subject 10 */ 11 void update(Subject subject); 12 13 }
1 /** 2 * 主題對象(目標對象) 3 * @author CL 4 * 5 */ 6 public class Subject { 7 8 protected List<Observer> list; 9 10 public Subject() { 11 list = new ArrayList<Observer>(); 12 } 13 14 public void addObserver(Observer observer) { 15 list.add(observer); 16 } 17 18 public void removeObserver(Observer observer) { 19 list.remove(observer); 20 } 21 22 /** 23 * 通知因此觀察者更新狀態 24 */ 25 public void notifyAllObserver() { 26 for (Observer o : list) { 27 o.update(this); 28 } 29 } 30 31 32 }
1 /** 2 * 具體的目標對象 3 * @author CL 4 * 5 */ 6 public class ConcreteSubject extends Subject { 7 8 /** 9 * 狀態 10 */ 11 private int state; 12 13 public int getState() { 14 return state; 15 } 16 17 public void setState(int state) { 18 this.state = state; 19 //若主題對象(目標對象)發生的狀態發生改變,請通知全部觀察者更新狀態 20 this.notifyAllObserver(); 21 } 22 23 }
1 /** 2 * 觀察者 3 * @author CL 4 * 5 */ 6 public class ObserverA implements Observer { 7 8 private int myState; //myState須要和目標對象的state保持一致 9 10 @Override 11 public void update(Subject subject) { 12 myState = ((ConcreteSubject) subject).getState(); 13 } 14 15 public int getMyState() { 16 return myState; 17 } 18 19 public void setMyState(int myState) { 20 this.myState = myState; 21 } 22 23 }
測試:spa
1 /** 2 * 測試觀察者模式 3 * @author CL 4 * 5 */ 6 public class Client { 7 8 public static void main(String[] args) { 9 //目標對象 10 ConcreteSubject sub = new ConcreteSubject(); 11 12 //建立三個觀察者 13 ObserverA o1 = new ObserverA(); 14 ObserverA o2 = new ObserverA(); 15 ObserverA o3 = new ObserverA(); 16 17 //將這三個觀察者添加到目標對象subject的容器中 18 sub.addObserver(o1); 19 sub.addObserver(o2); 20 sub.addObserver(o3); 21 22 //修改目標對象的狀態值 23 sub.setState(100); 24 25 System.out.println(o1.getMyState()); 26 System.out.println(o2.getMyState()); 27 System.out.println(o3.getMyState()); 28 29 System.out.println("----------------------"); 30 31 //修改目標對象的狀態值 32 sub.setState(10); 33 34 System.out.println(o1.getMyState()); 35 System.out.println(o2.getMyState()); 36 System.out.println(o3.getMyState()); 37 } 38 }
控制檯輸出:code
100 100 100 ---------------------- 10 10 10
1 import java.util.Observable; 2 3 /** 4 * 目標對象 5 * @author CL 6 * 7 */ 8 public class ConcreteSubject extends Observable { 9 private int state; 10 11 public int getState() { 12 return state; 13 } 14 15 public void setState(int state) { 16 this.state = state; 17 18 setChanged(); //表示目標對象已經更改狀態 19 20 notifyObservers(); //通知全部觀察者 21 } 22 23 }
1 import java.util.Observable; 2 import java.util.Observer; 3 4 /** 5 * 觀察者對象 6 * @author CL 7 * 8 */ 9 public class ObserverA implements Observer { 10 11 private int myState; 12 13 @Override 14 public void update(Observable o, Object arg) { 15 myState = ((ConcreteSubject) o).getState(); 16 } 17 18 public int getMyState() { 19 return myState; 20 } 21 22 public void setMyState(int myState) { 23 this.myState = myState; 24 } 25 26 }
測試:server
1 /** 2 * 測試利用java.util.*包中的類Observable和接口Obsever實現的觀察者模式 3 * @author CL 4 * 5 */ 6 public class Client { 7 8 public static void main(String[] args) { 9 //目標對象 10 ConcreteSubject sub = new ConcreteSubject(); 11 12 //建立三個觀察者 13 ObserverA o1 = new ObserverA(); 14 ObserverA o2 = new ObserverA(); 15 ObserverA o3 = new ObserverA(); 16 17 //將這三個觀察者添加到目標對象subject的容器中 18 sub.addObserver(o1); 19 sub.addObserver(o2); 20 sub.addObserver(o3); 21 22 //修改目標對象的狀態值 23 sub.setState(666); 24 25 System.out.println(o1.getMyState()); 26 System.out.println(o2.getMyState()); 27 System.out.println(o3.getMyState()); 28 29 System.out.println("----------------------"); 30 31 //修改目標對象的狀態值 32 sub.setState(123); 33 34 System.out.println(o1.getMyState()); 35 System.out.println(o2.getMyState()); 36 System.out.println(o3.getMyState()); 37 } 38 }
控制檯輸出:對象
666 666 666 ---------------------- 123 123 123
(1)手機APP中天天的推送廣告;
(2)多人聯機網絡遊戲中,服務器實時分發全部玩家的狀態;
(3)Servlet 中監聽器的實現;
(4)Android 中廣播機制;
(5)JDK 的 AWT 事件處理模型,基於觀察者模式的委派事件模型(Delegation Event Model)
事件源:目標對象
事件監聽器:觀察者
(6)…………