• 第二节:观察者模式——原理&应用


    一、观察者模式(Observer)原理

      1、观察者模式原理

        观察者模式类似于订牛奶业务:

        (1)奶站/气象局:Subject;

        (2)用户/第三方网站:Observer

        Subject:登记注册、移除和通知

        

         (1)registerObserver 注册

        (2)removeObserver 移除

        (3)notifyObserver() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取,也可能是实施推送,看具体需求;

        

        Observer:接收输入

        

         观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject 通知 Observer 变化,比如这里的奶站是 Subject,是 1 的一方,用户是 Observer,是多的一方。

     

    二、观察者模式应用

      1、思路分析图解(类图)

        

      2、代码实现

        Subject接口

    1 /**
    2  *  接口,让 WeatherData 来实现
    3  */
    4 public interface Subject {
    5 
    6     public void registerObserver(Observer o);
    7     public void removeObserver(Observer o);
    8     public void notifyObserver();
    9 }

        Subject实现类:

      1 /**
      2  * 核心类
      3  *  1、包含最新的天气情况信息
      4  *  2、包含 观察者集合,使用 ArrayList 管理
      5  *  3、当数据有更新时,就主动的调用 ArrayList,
      6  *      通知所有(接入方)就看到最新的信息
      7  *
      8  */
      9 public class WeatherData implements Subject{
     10 
     11     private float temperatrue;
     12     private float pressure;
     13     private float humidity;
     14 
     15     //观察者集合
     16     private ArrayList<Observer> observers;
     17 
     18     public WeatherData() {
     19         this.observers = new ArrayList<>();
     20     }
     21 
     22     /**
     23      * 注册一个观察者
     24      * @param o
     25      */
     26     @Override
     27     public void registerObserver(Observer o) {
     28         observers.add(o);
     29     }
     30 
     31     /**
     32      * 移除一个观察者
     33      * @param o
     34      */
     35     @Override
     36     public void removeObserver(Observer o) {
     37         if (observers.contains(o)) {
     38             observers.remove(o);
     39         }
     40     }
     41 
     42     //遍历所有的观察者,并通知
     43     @Override
     44     public void notifyObserver() {
     45         for (int i = 0; i < observers.size(); i++) {
     46             observers.get(i).update(temperatrue, pressure, humidity);
     47         }
     48     }
     49 
     50 
     51     /**
     52      * 当数据有更新时就调用 setData
     53      * @param temperature
     54      * @param pressure
     55      * @param humidity
     56      */
     57     public void setData(float temperature, float pressure, float humidity) {
     58         this.temperatrue = temperature;
     59         this.pressure = pressure;
     60         this.humidity = humidity;
     61         //调用 dataChange 方法,将最新信息 推送给 接入方 currentConditions
     62         dataChange();
     63     }
     64 
     65     //通知所有
     66     public void dataChange() {
     67         notifyObserver();
     68     }
     69 
     70 
     71     public float getTemperatrue() {
     72         return temperatrue;
     73     }
     74 
     75     public void setTemperatrue(float temperatrue) {
     76         this.temperatrue = temperatrue;
     77     }
     78 
     79     public float getPressure() {
     80         return pressure;
     81     }
     82 
     83     public void setPressure(float pressure) {
     84         this.pressure = pressure;
     85     }
     86 
     87     public float getHumidity() {
     88         return humidity;
     89     }
     90 
     91     public void setHumidity(float humidity) {
     92         this.humidity = humidity;
     93     }
     94 
     95     public ArrayList<Observer> getObservers() {
     96         return observers;
     97     }
     98 
     99     public void setObservers(ArrayList<Observer> observers) {
    100         this.observers = observers;
    101     }
    102 }

        观察者接口Observer:

    1 /**
    2  * 观察者接口,由观察者来实现
    3  */
    4 public interface Observer {
    5 
    6     public void update(float temperatrue, float pressure, float humidity);
    7 }

        观察者实现类:

     1 public class CurrentConditions implements Observer{
     2     private float temperature; //温度
     3     private float pressure;    //气压
     4     private float humidity;    // 湿度
     5 
     6 
     7     /**
     8      * 更新天气情况,是由 WeatherData 来调用,使用的是 推送模式
     9      * @param temperature
    10      * @param pressure
    11      * @param humidity
    12      */
    13     @Override
    14     public void update(float temperature, float pressure, float humidity) {
    15         this.temperature = temperature;
    16         this.pressure = pressure;
    17         this.humidity = humidity;
    18         display();
    19     }
    20 
    21 
    22     /**
    23      * 显示信息
    24      */
    25     public void display() {
    26         System.out.println("***Today mTemperature: " + temperature + "***");
    27         System.out.println("***Today mPressure: " + pressure + "***");
    28         System.out.println("***Today mHumidity: " + humidity + "***");
    29     }
    30 }
    31 
    32 --------------------------------------------------
    33 public class BaiduSite implements Observer{
    34 
    35     private float temperature; //温度
    36     private float pressure;    //气压
    37     private float humidity;    // 湿度
    38 
    39     @Override
    40     public void update(float temperatrue, float pressure, float humidity) {
    41         this.temperature = temperature;
    42         this.pressure = pressure;
    43         this.humidity = humidity;
    44         display();
    45     }
    46 
    47     /**
    48      * 显示信息
    49      */
    50     public void display() {
    51         System.out.println("***百度天气信息***");
    52         System.out.println("***百度网站:Today mTemperature: " + temperature + "***");
    53         System.out.println("***百度网站:Today mPressure: " + pressure + "***");
    54         System.out.println("***百度网站:Today mHumidity: " + humidity + "***");
    55     }
    56 }

        客户端:

     1 public class Client {
     2     public static void main(String[] args) {
     3 
     4         //1.创建 WeatherData
     5         WeatherData weatherData = new WeatherData();
     6 
     7         //2.创建观察者
     8         CurrentConditions currentConditions = new CurrentConditions();
     9 
    10         //3.注册到 weatherData 中
    11         weatherData.registerObserver(currentConditions);
    12 
    13 
    14         //再次创建观察者
    15         BaiduSite baiduSite = new BaiduSite();
    16         weatherData.registerObserver(baiduSite);
    17 
    18         //4.测试
    19         System.out.println("通知各个注册的观察者,看看信息");
    20 
    21         weatherData.setData(10, 100, 30.3f);
    22 
    23 
    24     }
    25 }

    三、观察者模式的好处

      1、观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知;

      2、这样,我们增加观察者(这里可以理解成一个新的公告板),就不需要去修改核心类 WeatherData 不会修改代码,遵守了 OCP 原则;

  • 相关阅读:
    用js实现cookie的读、写、全部删除和删除指定cookie值的删除---源码
    JS手机号码格式验证
    vuex
    解决“此图片来自微信公众平台未经允许不可引用”的方法
    二叉树
    剑指 Offer 10- II. 青蛙跳台阶问题
    logrotate处理Gunicorn日志
    Linux日志切割神器logrotate原理介绍和配置详解
    Jenkins任务启动的后台进程被自动kill
    Flex、Grid、媒体查询实现响应式布局
  • 原文地址:https://www.cnblogs.com/niujifei/p/14413985.html
Copyright © 2020-2023  润新知