下面是阅读《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 之 JDK内置的实现

    文章目录 概念 Code [主题] [观察者s] 观察者一 观察者二 [测试] 源码分析 java.util.Observable 目标类 java.util.Observer 观察者接口 notif ...

  2. Java设计模式——行为型模式之观察者模式

    一.前言 在生活中我们会遇到这样的场景:用水壶烧开水.当水烧开时,你会有一个关火的过程.在烧水的过程中,你一直观察着这个烧水的进度,当它的状态改变时会触发你关火的这个动作.观察者模式就是处理这种场景而 ...

  3. 设计模式——行为型模式_观察者模式/发布-订阅模式

    1. 类图 2. 角色 Subject:被观察者,抽象类 ConcreteSubject:被观察者的具体类,每个具体类中有列表记录任意数量的观察者 Observer:观察者接口 ConcrereObs ...

  4. 设计模式 - 创建型模式_ 单例模式 Singleton Pattern

    文章目录 概述 特点 懒汉式单例 饿汉式单例 饿汉式和懒汉式区别 概述 新总结了一篇单例模式的(2019-02-21),看这篇就够了 并发编程-09安全发布对象的4种方式 单例模式确保某各类只有一个实 ...

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

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  6. 设计模式-行为型模式-Observer 观察者模式

    设计模式-行为型模式-Observer 观察者模式 1.简介 软件程序之间的解耦,减少相互之间的依赖关系,但是模块之间又是需要协同工作的: 观察者模式使得一个对象的状态发生改变的时候,已经预约的其他对 ...

  7. 23种设计模式-行为型模式-观察者模式

    概述 它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多 ...

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

    设计模式-观察者模式 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观 ...

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

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

最新文章

  1. 【百度地图API】建立全国银行位置查询系统(四)——如何利用百度地图的数据生成自己的标注...
  2. 使用jq.lazyload.js,解决设置loading图片的问题
  3. iOS 利用长按手势移动 Table View Cells
  4. java怎样输出一个文件夹,java合并一个文件夹下所有txt文件,输出到另一个txt,...
  5. C语言实现二叉树-04版
  6. 【BZOJ2594】水管局长加强版,LCT+并查集+二分查找位置
  7. P1540 机器翻译 模拟
  8. 美股涨跌幅限制是多少?
  9. 1029 C语言文法定义与C程序的推导过程
  10. Diffusion扩散模型简述 + 代码demo
  11. plc通讯的握手信号_PLC工程师教你:从原理搞懂RS485串口通讯
  12. AVOD-理解系列(二)
  13. 安川机器人如何注释化指令_安川机器人指令一览
  14. jQuery TagsInput
  15. 360路由器虚拟服务器怎么设置,路由器端口映射设置步骤
  16. shiro学习一 (开涛的跟我学系列 ) 身份验证
  17. 【毕业设计/图像识别系列】基于凸包检测和重心距离法的指尖检测和识别【含Python源码】
  18. 华为手机开源内核代码
  19. 域格模块移动网络信号指标介绍
  20. 抱怨,是对自己无能的愤慨

热门文章

  1. 正则神器,RegexBuddy
  2. 数种国内无盘技术介绍与深入解析(转)
  3. 一个80后男生的择偶标准
  4. TM4C123GLaunchPad教程三_外部中断
  5. char* buf和char buf[64],定义两种字符串作为参数传递给函数的区别
  6. 跟我一起学习VIM - The Life Changing Editor
  7. C++基础之C++中的输入输出
  8. 80万册,吴军博士的数学书为什么这么强?
  9. 基于matlab的BOC调制信号捕获仿真
  10. arm linux 申请gpio,Linux GPIO 的注册与申请