zoukankan      html  css  js  c++  java
  • 观察者模式

    概述

    如果一个对象A的行为依赖另一个对象B的状态,我们可以有两种实现方式:

    一种是对象A轮询对象B的状态,根据轮询结果决定自己的行为;另一种是对象B在自身状态发生改变时,主动通知对象A。

    不难看出,第二种凡是会比第一种方式效率高,观察者模式即采用第二种方式,观察者模式可以用于事件监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。

    类图

     

     主题接口依赖观察者接口,因为要在主题中注册观察者(观察者订阅主题)

     

    jdk已经提供了观察者模式

    实例

    Observer

     1 /**
     2  * 观察者接口
     3  *
     4  * @author zhya
     5  * @date 2018/9/14
     6  **/
     7 public interface IObserver {
     8     /**
     9      * 通知
    10      *
    11      * @param event
    12      */
    13     void update(Event event);
    14 }

    Concrete Observer

     1 /**
     2  * 实际观察者
     3  *
     4  * @author zhangyang
     5  * @date 2018/9/14
     6  **/
     7 public class Observer implements IObserver {
     8     private String name;
     9 
    10     public Observer(String name) {
    11         this.name = name;
    12     }
    13 
    14     /**
    15      * 通知
    16      *
    17      * @param event
    18      */
    19     @Override
    20     public void update(Event event) {
    21         System.out.println(new StringBuffer("observer ").append(this.name).append(" received notification : ").append(event.getMsg()));
    22     }
    23 }

    Subject

     1 /**
     2  * 主题/被观察者接口
     3  *
     4  * @author zhangyang
     5  * @date 2018/9/14
     6  **/
     7 public interface ISubject {
     8     /**
     9      * 注册监听者
    10      *
    11      * @param observer
    12      */
    13     void attach(IObserver observer);
    14 
    15     /**
    16      * 注销监听者
    17      *
    18      * @param observer
    19      */
    20     void deattach(IObserver observer);
    21 
    22     /**
    23      * 变更通知
    24      *
    25      * @param event
    26      */
    27     void inform(Event event);
    28 }

    Concrete Subject

     1 import java.util.List;
     2 import java.util.Vector;
     3 
     4 /**
     5  * 实际主题/被观察者
     6  *
     7  * @author zhangyang
     8  * @date 2018/9/14
     9  **/
    10 public class Subject implements ISubject {
    11     private final List<IObserver> observers = new Vector<>();
    12 
    13     /**
    14      * 注册监听者
    15      *
    16      * @param observer
    17      */
    18     @Override
    19     public void attach(IObserver observer) {
    20         if (!observers.contains(observer)) {
    21             observers.add(observer);
    22         }
    23     }
    24 
    25     /**
    26      * 注销监听者
    27      *
    28      * @param observer
    29      */
    30     @Override
    31     public void deattach(IObserver observer) {
    32         observers.remove(observer);
    33     }
    34 
    35     /**
    36      * 变更通知
    37      *
    38      * @param event
    39      */
    40     @Override
    41     public void inform(Event event) {
    42         System.err.println("subject has new event : " + event.toString());
    43         observers.forEach(observer -> observer.update(event));
    44     }
    45 }

    Main测试类

     1 /**
     2  * 测试类
     3  *
     4  * @author zhya
     5  * @date 2018/9/14
     6  **/
     7 public class Main {
     8     public static void main(String[] args) {
     9         // 监听者
    10         IObserver observer1 = new Observer("observer1");
    11         IObserver observer2 = new Observer("observer2");
    12 
    13         // 主题
    14         ISubject subject = new Subject();
    15 
    16         // 注册监听
    17         subject.attach(observer1);
    18         subject.attach(observer2);
    19 
    20         // 主题状态变更
    21         Event event = new Event("ding ding");
    22         subject.inform(event);
    23         System.out.println("------------------------------------------");
    24 
    25         // 注销监听
    26         subject.deattach(observer1);
    27 
    28         // 主题状态变更
    29         event = new Event("dang dang");
    30         subject.inform(event);
    31 
    32     }
    33 }

    执行结果

  • 相关阅读:
    NGUI UIPanel绘制原理学习
    常用转义符
    windows常用快捷键
    用泛型方法Java从实体中提取属性值,以及在泛型方法中的使用
    java浮点型数据保留两位小数
    springboot中静态属性/静态方法从YAML(yml)读取配置属性
    Field in required a single bean, but 2 were found:
    Centos7 安装 Amazon Corretto 8
    Strange Java syntax (for me at least)--怪异的Java语法
    Returning array from function in C
  • 原文地址:https://www.cnblogs.com/zhya/p/9644652.html
Copyright © 2011-2022 走看看