博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式第二篇-观察者模式
阅读量:5058 次
发布时间:2019-06-12

本文共 4295 字,大约阅读时间需要 14 分钟。

一、引言

什么是观察者模式呢?其实生活中很常见:报社出版报纸,并定期向订阅用户推送报纸,用户可以订阅报纸和取消订阅。这个例子中可以看出观察者模式的主体有两个,即:出版者+订阅者,我们改个名称:出版者改为“主题”,订阅者改为“观察者”。

二、观察者模式

定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

三、实现

实例剖析:一个气象监测应用,气象监测系统定时会更新气象的相关数据,而对应有三种布告板都要显示此信息(显示的形式有所不同),一旦气象数据有所改动,三块布告板的数据也要同时的更新布告板中的显示信息。

分析:从需求中很容易看出:气象数据是主题,而三块布告板是观察者。要实现管理订阅者,则主题中必须存在一个数组列表用户管理。有一个方法进行数据推送更新,而订阅者的实现比较简单,他们继承统一的订阅接口,并且有一个更新数据方法。

类图:

代码实现:

主题及观察者接口

// 观察者接口public interface Observer {    public void update(float temp, float humidity, float pressure);}//主题接口public interface Subject {    //注册观察者    void registerObserver(Observer o);    //移除观察者    void removeObserver(Observer o);    //通知观察者    void notifyObservers();}//布告板接口public interface DisplayElement {    void display();}

 

主题实现

//主题实现public class WeatherData implements Subject {    //订阅者列表    private ArrayList observers;    private float temperature;    private float humidity;    private float pressure;    public WeatherData(){        observers=new ArrayList();    }    //增加订阅者    public void registerObserver(Observer o) {        observers.add(o);    }    //移除订阅者    public void removeObserver(Observer o) {        int index=observers.indexOf(o);        if(index>=0) {            observers.remove(index);        }    }    //通知订阅者    public void notifyObservers() {        for (int i = 0; i 

观察者实现

public class CurrentConditionsDisplay implements DisplayElement,Observer {    private float temperature;    private float humidity;    private Subject weatherData;    public CurrentConditionsDisplay(Subject weatherData) {        this.weatherData = weatherData;        weatherData.registerObserver(this);    }    public void display() {        System.out.println("第一种显示方式: " + temperature                + "F degrees and " + humidity + "% humidity");    }    public void update(float temp, float humidity, float pressure) {        this.temperature = temp;        this.humidity = humidity;        display();    }}
public class StatisticsDispxlay implements DisplayElement,Observer {    private float temperature;    private float pressure;    private Subject weatherData;    public StatisticsDispxlay(WeatherData weatherData){        this.weatherData=weatherData;    }    public void display() {        System.out.println("第二种显示方式: " + temperature                + "F degrees and " + pressure + "% pressure");    }    public void update(float temp, float humidity, float pressure) {        this.temperature=temp;        this.pressure=pressure;    }}
public class ForecastDisplay implements DisplayElement,Observer {    private  float humidity;    private  float pressure;    private WeatherData weatherData;    public ForecastDisplay(WeatherData weatherData){        this.weatherData=weatherData;    }    public void display() {        System.out.println("第三种显示方式: " + humidity                + "F degrees and " + pressure + "% pressure");    }    public void update(float temp, float humidity, float pressure) {        this.humidity=humidity;        this.pressure=pressure;    }}
 

 

 

运行:

private static void observer() {        WeatherData weatherData = new WeatherData();        CurrentConditionsDisplay currentDisplay =                new CurrentConditionsDisplay(weatherData);        StatisticsDispxlay statisticsDisplay = new StatisticsDispxlay(weatherData);        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);        weatherData.setMeasurements(80, 65, 30.4f);        weatherData.setMeasurements(82, 70, 29.2f);        weatherData.setMeasurements(78, 90, 29.2f);    }

运行结果:

四、优缺点

观察者模式有以下几个优点:

  • 观察者模式实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层,即观察者。
  • 观察者模式在被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。
  • 观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知。

观察者也存在以下一些缺点:

  • 如果一个被观察者有很多直接和间接的观察者时,将所有的观察者都通知到会花费很多时间。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发送了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎样发生变化的。
  • 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃,在使用观察者模式应特别注意这点。

结语:java中有内置的观察者模式,java.util包(package)内包含最基本的Observer接口与Observable类,这和我们的Subject接口与Observer接口很相似。里面还增加了状态的判断,这样可以让订阅者能够自主的拉取。

 

转载于:https://www.cnblogs.com/yuanqinnan/p/10149453.html

你可能感兴趣的文章
Range和xrange的区别
查看>>
BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)
查看>>
java-动态规划算法学习笔记
查看>>
STL容器之vector
查看>>
Linux 内核中断内幕
查看>>
DNS负载均衡
查看>>
无法向会话状态服务器发出会话状态请求
查看>>
数据中心虚拟化技术
查看>>
Oracle OEM 配置报错: No value was set for the parameter DBCONTROL_HTTP_PORT 解决方法
查看>>
01入门
查看>>
python正则表达式
查看>>
嵌套循环连接(nested loops join)原理
查看>>
shell统计特征数量
查看>>
复习文件操作
查看>>
C#Hashtable与Dictionary性能
查看>>
10个让你忘记 Flash 的 HTML5 应用演示
查看>>
8个Python面试必考的题目,小编也被坑过 ToT
查看>>
SQL Server 使用作业设置定时任务之一(转载)
查看>>
centos 图形界面和命令行界面切换(转载)
查看>>
Maven启用代理访问
查看>>