JDK使用最多的模式之一--观察者模式

公司接到新任务,需要做一个气象监测应用。该应用将实现三个界面:当前气象状态,气象统计以及气象预报。应用从WeatherObject对象中获取所需数据:温度,湿度,气压。当然,为了可扩展性,该应用同时也要求提供api给其他开发者以便他们开发自己的气象面板。如下图

WeatherData中的方法,3个get方法将返回最新的测量数据,measurementsChanged在气象数据更新时被调用,该方法也是我们需要完成的。

现在我们开始来完成任务

第一次设计:先将三个参数由get方法获得,接着调用三个面板的update方法,并传入这三个参数

但在这个实现中,我们可以发现update可以被封装,且多个display违背了针对接口而不针对实现编程的原则

在这里,我们引入Observer模式,下图为总体设计

在这里,我们可以将Subject比喻为一家报社,Observer则是订阅报纸的人,人可以选择订阅或者取消订阅报纸,而报社则有义务随时将最新消息发送给订阅者。

我们首先定义了三个接口,分别是Subject(主题),Observer(观察者)和DisplayElement(显示)

具体看代码:

public interface Subject {
    public void registerObserver(Observer o);    //注册观察者
    public void removeObserve(Observer o);        //删除观察者
    public void notifyObservers();                //更新观察者数据(即发送最新的报纸)
}
public interface Observer {
    public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
    public void display();
}

这样,我们就将update和display独立为接口了

接着,我们实现Subject(主题),或者说实现报社的功能,将订阅者作为list,新增删除就用list的方法,而通知就用for循环,将最新信息发送给所有订阅者,

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        // TODO Auto-generated constructor stub
        observers = new ArrayList();
    }

    @Override
    public void registerObserver(Observer o) {
        // TODO Auto-generated method stub
        observers.add(o);
    }

    @Override
    public void removeObserve(Observer o) {
        // TODO Auto-generated method stub
        int i = observers.indexOf(o);
        if(i >= 0) {
            observers.remove(i);
        }
    }

    @Override
    public void notifyObservers() {
        // TODO Auto-generated method stub
        for(int i = 0; i < observers.size(); i ++) {
            Observer observer = (Observer)observers.get(i);
            observer.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

}

接着实现一名订阅者,订阅者实现update和display方法,并且在构造函数中注册成为一名观察者

public class CurrentConditionsDisplay implements Observer, DisplayElement {

    private float temperature;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionsDisplay(Subject weatherData) {
        // TODO Auto-generated constructor stub
        this.weatherData = weatherData;
        this.weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("Current condition:" + temperature + "F degree and " + humidity + "% humidity");
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        // TODO Auto-generated method stub
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

}

最后,在main方法中,我们建了(实例化)一个报社,一个订阅者。并将报社作为参数传给订阅者。随后,报社便不停更新数据,而订阅者也会不停接收最新的信息。

public class WeatherStation {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        weatherData.setMeasurements(80, 65, 3.4F);
        weatherData.setMeasurements(82, 70, 3.5F);
        weatherData.setMeasurements(78, 90, 3.6F);
    }

}
时间: 2024-10-19 13:14:11

JDK使用最多的模式之一--观察者模式的相关文章

Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 ),利用RTTI实现Delphi的多播事件代理研究

Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 )http://www.cnblogs.com/hezihang/p/6083555.html 利用RTTI实现Delphi的多播事件代理研究http://www.cnblogs.com/hezihang/p/3299481.html

(19):(行为型模式) Observer 观察者模式

(19):(行为型模式) Observer 观察者模式,布布扣,bubuko.com

2015-03-12---外观模式,建造者模式,观察者模式,boost库应用

今天白天主要看了boost库的应用,主要是常用的一些库,array,bind,function,regex,thread,unordered,ref,smartpointers库,晚上看了看设计模式,主要就是外观模式,建造者模式和观察者模式.我们从boost简要说起. 其实boost的库好多东西在c++11里面已经有了,比如bind,只不过boost的库的bind比c++11用着感觉要方便,其实有些东西我自己因为也没有用c++做过什么大的项目,所以不敢乱说,只敢说点建议性的,关于bind就是绑定

行为型模式之观察者模式

概述 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展. 定义 观察者模式(Observer Pattern):定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.

常见的设计模式:单例模式、工厂模式、观察者模式、装饰模式与适配器模式

常见的设计模式:单例模式.工厂模式.观察者模式.装饰模式与适配器模式 这里可以阅读Terry Lee的设计模式系列来理解学习一下 1.4.1 单例模式 .NET设计模式(2):单件模式(Singleton Pattern)  http://terrylee.cnblogs.com/archive/2005/12/09/293509.html 1.4.2 抽象工厂模式 .NET设计模式(3):抽象工厂模式(Abstract Factory) http://terrylee.cnblogs.com/

EventBus事件总线框架(发布者/订阅者模式,观察者模式)

一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. Intent进行组件间通信,广播方式. 二.单例比较好的写法: private static volatile EventBus defaultInstance; 构造函数应当是private,不应该是public 1 public static EventBus getDefault() { 2 if

反应器模式 vs 观察者模式

反应器模式(Reactor pattern)与观察者模式(Observer pattern) 反应器模式 是一种为处理服务请求并发提交到一个或者多个服务处理程序的事件设计模式.当请求抵达后,服务处理程序使用解多路分配策略,然后同步地派发这些请求至相关的请求处理程序. 观察者模式 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 将事件多路分用.将事件分派到各自相应的

责任链模式和观察者模式实现一个简易的架构(一)

场景描述: 以金融行业的贷款业务为例,客户提交贷款申请,即进件.系统针对进件需要做一系列处理:保存申请信息.保存客户信息.对客户评分.触发风控检查.埋点.消推等. 传统编码方式: 竖向编程方式,就是按照逻辑一步一步执行.这样做的缺点,就是代码耦合度太高. 使用责任链模式和观察者模式解耦: 责任链模式:以单向链表为结构,一步一步执行,每一个businessHandlerContext(对应一个businessHandler)为一个执行单元,代码解耦.所有的操作属于一个事务. 观察者模式:针对需要异

Java设计模式补充:回调模式、事件监听器模式、观察者模式(转)

一.回调函数 为什么首先会讲回调函数呢?因为这个是理解监听器.观察者模式的关键. 什么是回调函数 所谓的回调,用于回调的函数. 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数. 有这么一句通俗的定义:就是程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法. 举个例子: 这里有两个实体:回调抽象接口.回调者(即程序a) 回调接口(ICallBack ) public i