设计模式----行为型模式之观察者模式(Observer Pattern)

  下面是阅读《Head First设计模式》的笔记。

观察者模式

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

JDK API内置机制

  JDK1.0版本就已经包含了java.util.Observer和java.util.Observable,TODO。

  java.util.Observer是一个接口,所有使用内置机制实现观察者模式,都需要实现该接口。该接口只定义了一个方法 void update(Observable o, Object arg),实现该接口的类(观察者)需要重新该方法,当主题(可观察的)状态改变时,会通知观察者更新实时信息,每一个观察者获取到改变的数据,做出相应的实现(需求不一致),类似于书中介绍的状态布告板、统计布告板和预测布告板等。

  java.util.Observable是一个类,这个类或者继承改类的(继承基类的行为),内置构造和方法如图所示(省事截图):

  

  Observable类中的setChanged()方法提供了更多弹性,当继承该类是,可以调用该方法,根据自己的需求,适当地改变状态,再通知每一个观察者实现通知的功能。

使用观察者模式实现的例子

  

/**
 * 天气主题(可观察者/目标)
 * @author mjs
 * @version 1.0.0
 * @filename WeatherData.java
 * @time 2017-3-9 下午8:26:48
 * @copyright(C) 2017 **********有限公司
 */
package com.shing.design.observerpattern;

import java.util.Observable;

public class WeatherData extends Observable {
    private float temperature; //温度
    private float humidity; //湿度
    private float pressure; //气压
    public float getTemperature() {
        return temperature;
    }

    public WeatherData() {
        // TODO Auto-generated constructor stub
    }
    /**
     * 改变状态,通知观察者(布告板)
     */
    public void measurementsChanged(){
        setChanged();
        notifyObservers();
    }

    /**
     * 当气象台检测到变化是调用该方法
     * @param temperature 温度
     * @param humidity 湿度
     * @param pressure 大气压
     */
    public void setMeasurements(float temperature, float humidity, float pressure){
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

    public void setTemperature(float temperature) {
        this.temperature = temperature;
    }
    public float getHumidity() {
        return humidity;
    }
    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }
    public float getPressure() {
        return pressure;
    }
    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}
/**
 * 显示要素
 * @author mjs
 * @version 1.0.0
 * @filename DisplayElement.java
 * @time 2017-3-9 下午8:24:49
 * @copyright(C) 2017 **********有限公司
 */
package com.shing.design.observerpattern;

public interface DisplayElement {
    /**
     * 显示元素方法
     */
    void display();
}
/**
 * 目前状况布告板
 * @author mjs
 * @version 1.0.0
 * @filename CurrentConditionsDisplay.java
 * @time 2017-3-11 上午9:35:45
 * @copyright(C) 2017 **********有限公司
 */
package com.shing.design.observerpattern;

import java.util.Observable;
import java.util.Observer;

public class CurrentConditionsDisplay implements Observer, DisplayElement {
    Observable observable;
    private float temperature;
    private float humidity;

    /**
     * 初始化构造,并注册到气象台
     * @param observable
     */
    public CurrentConditionsDisplay(Observable observable) {
        super();
        this.observable = observable;
        observable.addObserver(this);
    }

    /*
     * 布告板显示
     */
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("【目前状况布告板】当前状况:" + temperature + "华摄氏度, " + humidity + "%湿度");
    }

    /*
     *
     */
    public void update(Observable obs, Object arg) {
        if(obs instanceof WeatherData){
            WeatherData weatherData = (WeatherData) obs;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }

}
/**
 * 预测布告板
 * @author mjs
 * @version 1.0.0
 * @filename ForecastDisplay.java
 * @time 2017-3-11 上午9:53:09
 * @copyright(C) 2017 **********有限公司
 */
package com.shing.design.observerpattern;

import java.util.Observable;
import java.util.Observer;

public class ForecastDisplay implements DisplayElement, Observer {
    Observable observable;
    private float currentPressure = 29.92f;
    private float lastPressure;
    /**
     * 初始化预测布告板,并注册在气象台
     * @param observable
     */
    public ForecastDisplay(Observable observable) {
        super();
        this.observable = observable;
        observable.addObserver(this);
    }

    /*
     * 更新状态
     */
    public void update(Observable o, Object arg) {
        // TODO Auto-generated method stub
        if(o instanceof Observable){
            WeatherData weatherData = (WeatherData) o;
            lastPressure = currentPressure;
            currentPressure = weatherData.getPressure();
            display();
        }
    }

    /*
     *
     */
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("【预测布告板】当前气压:" + currentPressure + ",最新气压:" + lastPressure);
    }

}
/**
 * 测试类
 * @author mjs
 * @version 1.0.0
 * @filename Test.java
 * @time 2017-3-11 上午10:21:59
 * @copyright(C) 2017 **********有限公司
 */
package com.shing.design.observerpattern;

public class Test {
    public static void main(String[] args) {
        WeatherData weatherDate = new WeatherData();
        CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherDate);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherDate);
        weatherDate.setMeasurements(57, 87, 110);
    }
}
/**
    Console:
    【预测布告板】当前气压:110.0,最新气压:29.92
    【目前状况布告板】当前状况:57.0华摄氏度, 87.0%湿度
*/

推模型和拉模型

  推模型: 主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。

  拉模型:主题对象在通知观察者的时候,只传递少量信息。(上述的例子就是该种模型,如果推模型,请自行脑补哈)。

  注:JDK API中都实现了观察者模式,JavaBeans和Swing,Swing API中JButton类所实现的超类AbstractButton,会看到许多增加与删除倾听者(listener)的方法,这些方法可以让观察者感应到Swing组件的不同类型事件。

结束语

 多学习一点,人生多一分精彩!

  

时间: 2024-10-12 17:01:16

设计模式----行为型模式之观察者模式(Observer Pattern)的相关文章

设计模式-行为型模式,观察者模式(13)

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象.观察者模式属于行为型模式. 有时,我们希望在一个对象的状态改变时更新另外一组对象. class Publisher: def __init__(self): self.observers = [] def add(self, observer): if observer not in self.observers: self.observers.append(obs

设计模式(行为型)之观察者模式(Observer Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之代理模式(Proxy Pattern)>http://blog.csdn.net/yanbober/article/details/45480965 概述 观察者模式用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作

设计模式 - 观察者模式(Observer Pattern) Java内置 使用方法

观察者模式(Observer Pattern) Java内置 使用方法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 观察者模式(observer pattern)详解, 参见: http://blog.csdn.net/caroline_wendy/article/details/26583157 Java内置的观察者模式, 是通过继承父类, 实现观察者模式的几个主要函数: Observerable(可被观

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型.该模式有两个角色,一个是Subject, 另一个是Observer.Subject 保存有多个Observer的引用,一旦特定的事件发生,Subject会通知它所有的Observer,Observer得到该通知后执行相关程序逻辑.其中,Observer只有先向Subject注册后才能被Subject知晓.这就像订报纸,只有我们向出版社提出订报的申请,出版社才会把我们列入订阅者名单,然后每当新报纸印好时,出版社会通知订阅

设计模式 - 观察者模式(Observer Pattern) 详解

观察者模式(Observer Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权所有, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新. 使用方法: 1. 首先新建主题(subject)接口, 负责注册(register)\删除(remove

设计模式 - 观察者模式(Observer Pattern) 详细说明

观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的全部依赖者都会收到通知并自己主动更新. 用法: 1. 首先新建主题(subject)接口, 负责注冊(register)\删除(remo

行为型模式之观察者模式

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

设计模式——行为型模式

继<设计模式--创建型模式>和<设计模式--结构型模式>之后,今天介绍一下行为型模式. 行为模式设计到算法和对象间的职责分配,不仅描述对象或类的模式,还描述他们之间的通信方式,客服了运行时难以跟踪的复杂的控制流,他们将你的注意力重控制流转移到对象间的关系上来.行为类模式采用继承机制在类间分派行为,例:模板方法模式.解释器模式:行为对象模式描述了一组相互对等的对象如何相互协作以完成其中任何一个对象都单独无法完成的任务,例:中介者模式.职责链模式.策略模式:其它的行为对象模式常将行为封

JDK 源码 阅读 - 2 - 设计模式 - 创建型模式

A.创建型模式 抽象工厂(Abstract Factory) javax.xml.parsers.DocumentBuilderFactory DocumentBuilderFactory通过FactoryFinder实例化具体的Factory. 使用例子: DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilder