GOF23设计模式之观察者模式(observer)

一、观察者模式概述

  观察者模式主要用于 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)…………

posted @ 2018-01-23 09:49  C3Stones  阅读(348)  评论(0编辑  收藏  举报