GOF23設計模式之觀察者模式(observer)
阿新 • • 發佈:2018-01-23
hang 事件監聽器 rgs str arr public pda import lob
一、觀察者模式概述
觀察者模式主要用於 1 :N 的通知。當一個對象(目標對象 Subject 或 Observable)的狀態變化時,它需要通知一系列對象(觀察者對象 Observer),令它們做出響應。
通知觀察者的方式:
(1)推
每次都會把通知以廣播的方式發送給所有觀察者,所有觀察者只能被動接收。
(2)拉
觀察者只要知道有情況即可。至於什麽時候獲取內容,獲取哪些內容,都可以自主決定。
二、觀察者模式示例代碼
1 /** 2 * 觀察者對象接口 3 * @author CL 4 * 5 */ 6 public interfaceObserver { 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 }
測試:
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 }
控制臺輸出:
100 100 100 ---------------------- 10 10 10
三、JDK 中提供類和方法實現觀察者模式
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 }
測試:
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)…………
GOF23設計模式之觀察者模式(observer)