设计模式----行为型模式之观察者模式(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组件的不同类型事件。
结束语
多学习一点,人生多一分精彩!
设计模式----行为型模式之观察者模式(Observer Pattern)的更多相关文章
- 十一个行为模式之观察者模式(Observer Pattern)
定义: 定义对象之间一种一对多的关系,当被观察者状态变化时,可以自动地通知观察者并执行相关的业务操作.观察者模式又被称为发布-订阅模式等. 结构图: Subject:抽象主题类,定义了所有被观察类的通 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
- 设计模式 - 观察者模式(Observer Pattern) Java内置 用法
观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细解释
观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 二十四种设计模式:观察者模式(Observer Pattern)
观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...
- jQuery中的观察者模式(Observer Pattern)
在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer Pattern). ■ on方法绑定内置事件, ...
- 被遗忘的设计模式——空对象模式(Null Object Pattern)
GoF(四人帮)那本<设计模式 可复用面向对象软件的基础>可谓是设计模式方面的经典之作,其中介绍的23种设计模式, 也可谓是经典中的经典.但是,设计模式的种类绝不仅仅是这23种,除此之外还 ...
随机推荐
- Codefroces 366 D Dima and Trap Graph (最短路)
Dima and Trap Graph 题意:Dima和Inna越来越喜欢对方,但是Dima的室友缺很没有热情出去玩,然后Dima就把他室友Seryozha骗进了陷阱里.现在Seryozha想要从陷阱 ...
- 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解
二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...
- SpringBoot发送邮箱验证码
一.开启QQ邮箱服务 (1)登陆QQ找到设置,点击账户 (2)往下拉,开启POP3/SMTP服务和IMAP/SMTP服务 当开启IMAP/SMTP会有一串密文密码,保存起来后面要用到 二.spring ...
- Oracle 11g Rac 用rman实现把本地数据文件迁移到ASM共享存储中
在Oracle Rac环境中,数据文件都是要存放在ASM共享存储上的,这样两个节点才能同时访问.而当你在某一节点下把数据文件创建在本地磁盘的时候,那么在另一节点上要访问该数据文件的时候就会报错,因为找 ...
- Linux基础Day001-001章
运维工作职责:(运行和维护服务器) 1.数据不能丢失, 2.保障网站7*24H正常运行,--一直运行; 3.用户体验要好,--打开网站速度要快 服务器核心硬件(硬盘,内存,CPU) 尺寸: 1U-4. ...
- CentOS 7 下网络无法访问 Failed to start LSB: Bring up/.
[root@localhost Desktop]# ping 192.168.2.1PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.64 byt ...
- d010:盈数、亏数和完全数
题目: 对一个正整数N而言,将它除了本身以外所有的因子加起来的总和为S,如果S>N,则N为盈数,如果S<N,则N为亏数,而如果S=N,则N为完全数(Perfect Number).例如10 ...
- (附源码gitHub下载地址)spring boot -jta-atomikos分布式事务
应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个Mysql.一个 ...
- 遇到XML-GB2312网页编码的处理方法
报的错误:encoding error : input conversion failed due to input error, bytes I/O error : encoder error 1 ...
- 48 (OC)* 适配iPad和iPhone、以及横竖屏适配。
一:核心方法 1.三个方法 1.1:开始就会触发 - (void)viewWillLayoutSubviews; 1.2:开始就会触发 - (void)viewDidLayoutSubviews; 1 ...