1. 程式人生 > >GOF23設計模式之觀察者模式(observer)

GOF23設計模式之觀察者模式(observer)

hang 事件監聽器 rgs str arr public pda import lob

一、觀察者模式概述

  觀察者模式主要用於 1 :N 的通知。當一個對象(目標對象 Subject 或 Observable)的狀態變化時,它需要通知一系列對象(觀察者對象 Observer),令它們做出響應。

  通知觀察者的方式:

    (1)推

       每次都會把通知以廣播的方式發送給所有觀察者,所有觀察者只能被動接收。

    (2)拉

       觀察者只要知道有情況即可。至於什麽時候獲取內容,獲取哪些內容,都可以自主決定。

二、觀察者模式示例代碼

 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 }

  測試:

 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)