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

1、觀察者模式概述

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

  通知觀察者的方式:服務器

    (1)推網絡

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

    (2)拉測試

        觀察者只要知道有狀況便可。至於何時獲取內容,獲取哪些內容,均可以自主決定。this

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 }

  測試: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

3、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 }

  測試: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

4、觀察者模式常見開發應用場景

  (1)手機APP中天天的推送廣告;

  (2)多人聯機網絡遊戲中,服務器實時分發全部玩家的狀態;

  (3)Servlet 中監聽器的實現;

  (4)Android 中廣播機制;

  (5)JDK 的 AWT 事件處理模型,基於觀察者模式的委派事件模型(Delegation Event Model)

      事件源:目標對象

      事件監聽器:觀察者

  (6)…………

相關文章
相關標籤/搜索