下面是阅读《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组件的不同类型事件。

结束语

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

  

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

  1. 十一个行为模式之观察者模式(Observer Pattern)

    定义: 定义对象之间一种一对多的关系,当被观察者状态变化时,可以自动地通知观察者并执行相关的业务操作.观察者模式又被称为发布-订阅模式等. 结构图: Subject:抽象主题类,定义了所有被观察类的通 ...

  2. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  3. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

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

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

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

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  6. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  7. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  8. jQuery中的观察者模式(Observer Pattern)

    在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer Pattern). ■ on方法绑定内置事件, ...

  9. 被遗忘的设计模式——空对象模式(Null Object Pattern)

    GoF(四人帮)那本<设计模式 可复用面向对象软件的基础>可谓是设计模式方面的经典之作,其中介绍的23种设计模式, 也可谓是经典中的经典.但是,设计模式的种类绝不仅仅是这23种,除此之外还 ...

随机推荐

  1. 微信公众号之获取openId

    在小伙伴们开发微信公众号.小程序或者是在微信内置浏览器打开的项目时,会遇到的第一个问题就是如何获取openId,今天小编就给大家带来的是如何获取openId. 首先   我们要从微信开发者后台得到ap ...

  2. 【LeetCode】240-搜索二维矩阵 II

    题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 m ...

  3. java8函数式接口详解、函数接口详解、lambda表达式匿名函数、方法引用使用含义、函数式接口实例、如何定义函数式接口

    函数式接口详细定义 函数式接口只有一个抽象方法 由于default方法有一个实现,所以他们不是抽象的. 如果一个接口定义了一个抽象方法,而他恰好覆盖了Object的public方法,仍旧不算做接口的抽 ...

  4. 小白专场-多项式乘法与加法运算-python语言实现

    目录 题意理解 解题思路 多项式加法 多项式乘法 完整代码 题意理解 题目: 设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一 ...

  5. MySQL Explain学习笔记

    目录 一.执行计划概念 二.Explain用法 三.Explain属性介绍 3.1 id属性 3.2 select_type属性 3.3 table属性 3.4 type属性 3.5 possible ...

  6. Java的初始化块及执行过程详解

    问题:Java对象初始化方式主要有哪几种?分别是什么?针对上面的问题,想必大家脑海中首先浮现出的答案是构造器,没错,构造器是Java中常用的对象初始化方式. 还有一种与构造器作用非常相似的是初始化块, ...

  7. FreeSql 新手上路系列教程已发布在 cnblogs

    FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) FreeSql采用MIT开源协议托管 ...

  8. 【Rocketmq】通过 docker 快速搭建 rocketmq 环境

    1. 安装 Namesrv 拉取镜像 docker pull rocketmqinc/rocketmq:4.4.0` 启动容器 docker run -d -p 9876:9876 -v {RmHom ...

  9. 各种浏览器UA值

    UA  User-Agent:用户代理,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本.CPU 类型.浏览器及版本.浏览器引擎.浏览器语言.浏览器插件等. 标准格式为: 浏览器标识 ...

  10. CSS——段落处理

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...