• 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)…………

  • 相关阅读:
    51Nod-1013 3的幂的和【快速模幂+逆元】
    51Nod-1082 与7无关的数【进制+打表】
    51Nod-1080 两个数的平方和【暴力法】
    51Nod-1015 水仙花数【进制+查表搜索】
    51Nod-1003 阶乘后面0的数量【分析思维】
    51Nod-1002 数塔取数问题【DP】
    51Nod-1179 最大的最大公约数【暴力】
    51Nod-1018 排序【排序】
    51Nod-1126 求递推序列的第N项【递推序列+模除】
    51Nod-1031 骨牌覆盖【递推】
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8334075.html
Copyright © 2020-2023  润新知