HeadFirst设计模式---观察者
表达公式
注册者 + 订阅者 = 观察者模式
设计气象站

气象站接口
/**
** 布告板
** @author lollipop
** @since 2019/11/24
**/
public interface DisplayElement {
/** 显示 **/
void display();
}
/**
* 观察者
* @author lollipop
* @since 2019/11/24
*/
public interface Observer {
/**
* 更新
* @param temperature
* @param humidity
* @param pressure
*/
void update(float temperature,float humidity,float pressure);
}
/**
* 主题接口
* @author lollipop
* @since 2019/11/24
*/
public interface Subject {
/**
* 注册
*/
void registerObserver(Observer o);
/**
* 注销
*/
void removeObserver(Observer o);
/**
* 通知
*/
void notifyObserver();
}
气象实现
/**
* @author lollipop
* @since 2019/11/24
*/
@Data
public class CurrentConditionsDisplay implements Observer, DisplayElement {
/**
* 温度
*/
private float temperature;
/**
* 湿度
*/
private float humidity;
/**
* 天气数据
*/
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
/**
* 显示
*/
public void display() {
System.out.println("Current conditions: " + temperature
+ "F degrees and " + humidity + "% humidity");
}
/**
* 更新
* @param temperature
* @param humidity
* @param pressure
*/
public void update(float temperature, float humidity, float pressure) {
this.humidity = humidity;
this.temperature = temperature;
display();
}
}
/**
* @author lollipop
* @since 2019/11/24
*/
public class ForecastDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
/**
* 天气数据
*/
private Subject weatherData;
/**
* 显示
*/
public void display() {
if (this.pressure < 10.0f) {
System.out.println("晴天");
} else if (this.pressure >= 10.0f && this.pressure < 50.0f) {
System.out.println("多云");
} else {
System.out.println("下雨");
}
}
public ForecastDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
/**
* 更新
*
* @param temperature
* @param humidity
* @param pressure
*/
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.display();
}
}
/**
* @author lollipop
* @since 2019/11/24
*/
public class StatisticsDisplay implements Observer, DisplayElement {
private float maxTemperatures = 0.00f;
private float minTemperatures = 0.00f;
private int count = 0;
private float totalTemperatures = 0.00f;
private float avgTemperatures = 0.00f;
/**
* 天气数据
*/
private Subject weatherData;
/**
* 显示
*/
public void display() {
System.out.println("maxTemperatures: " + maxTemperatures);
System.out.println("minTemperatures: " + minTemperatures);
System.out.println("avgTemperatures: " + avgTemperatures);
}
public StatisticsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
/**
* 更新
*
* @param temperature
* @param humidity
* @param pressure
*/
public void update(float temperature, float humidity, float pressure) {
if (this.maxTemperatures < temperature) {
this.maxTemperatures = temperature;
}
if (this.minTemperatures == 0.00f) {
this.minTemperatures = temperature;
} else if (this.minTemperatures > temperature) {
this.minTemperatures = temperature;
}
if (temperature > 0) {
totalTemperatures += temperature;
avgTemperatures = totalTemperatures / ++count;
}
this.display();
}
}
/**
* @author lollipop
* @since 2019/11/24
*/
@Data
public class WeatherData implements Subject {
/**
* 注入观察者
*/
List<Observer> observers = new ArrayList<Observer>(5);
/**
* 温度
*/
private float temperature;
/**
* 湿度
*/
private float humidity;
/**
* 气压
*/
private float pressure;
public WeatherData() {
}
/**
* 注册
*
* @param o
*/
public void registerObserver(Observer o) {
observers.add(o);
}
/**
* 注销
*
* @param o
*/
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(o);
}
}
/**
* 通知
*/
public void notifyObserver() {
for (Observer one : observers) {
one.update(temperature, humidity, pressure);
}
}
/**
* 通知观察者
*/
public void measurementsChanged() {
notifyObserver();
}
/**
* 设置数据
*
* @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();
}
}
气象站运行
/**
* @author lollipop
* @since 2019/11/25
*/
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
weatherData.setMeasurements(80,65,30.4f);
weatherData.setMeasurements(82,70,29.2f);
weatherData.setMeasurements(78,90,29.2f);
}
}
运行结果
Current conditions: 80.0F degrees and 65.0% humidity
maxTemperatures: 80.0
minTemperatures: 80.0
avgTemperatures: 80.0
多云
Current conditions: 82.0F degrees and 70.0% humidity
maxTemperatures: 82.0
minTemperatures: 80.0
avgTemperatures: 81.0
多云
Current conditions: 78.0F degrees and 90.0% humidity
maxTemperatures: 82.0
minTemperatures: 78.0
avgTemperatures: 80.0
多云
总结
- 需要List集合保存注册者
- 轮询注册者列表,动态调用注册者更新方法
HeadFirst设计模式---观察者的更多相关文章
- 《HeadFirst设计模式》读后感——对学习设计模式的一些想法
最近看完了<HeadFirst设计模式>,GOF的<设计模式——可复用面向对象软件的基础>的创建型模式也读完了,经历了从一无所知到茅塞顿开再到充满迷惑的过程. 不得不说< ...
- headfirst设计模式(2)—观察者模式
定义 观察者模式(有时又被称为发布(publish)-订阅(Subscribe)模式,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---观察者模式之WeatherReport[转]
1 2{<HeadFirst设计模式>之观察者模式 } 3{ 主题与观察者 } 4{ 编译工具 :Delphi7.0 ...
- 【Head-First设计模式】C#版-学习笔记-开篇及文章目录
原文地址:[Head-First设计模式]C#版-学习笔记-开篇及文章目录 最近一年断断续续的在看技术书,但是回想看的内容,就忘了书上讲的是什么东西了,为了记住那些看过的东西,最好的办法就是敲代码验证 ...
- Headfirst设计模式的C++实现——策略模式(Strategy)
前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h #inclu ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- headfirst设计模式(5)—工厂模式体系分析及抽象工厂模式
先编一个这么久不写的理由 上周我终于鼓起勇气翻开了headfirst设计模式这本书,看看自己下一个设计模式要写个啥,然后,我终于知道我为啥这么久都没写设计模式了,headfirst的这个抽象工厂模式, ...
- headfirst设计模式swift版01
headfirst设计模式这本书真好,准备用一个月学完.书里讲得很清楚了. 设计原则: 1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起. 2.针对接口编程,而不是针 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---工厂模式之简单工厂
简单工厂:工厂依据传进的参数创建相应的产品. http://www.cnblogs.com/DelphiDesignPatterns/archive/2009/07/24/1530536.html { ...
随机推荐
- Springboot中定时器的简单使用
在定时器的类上添加注解: @Component@EnableAsync@EnableScheduling 一.普通的定时器: 每天15:10执行的定时器 @Scheduled(cron="0 ...
- mysql判断是否包含某个字符的方法和修改表中指定字段
用locate 是最快的,like 最慢.position一般实战例子:select * from historydatawhere locate('0',opennum) and locate('1 ...
- 最短时间(几秒内)利用C#往SQLserver数据库一次性插入10万条数据
用途说明: 公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储.于是在网上进行查找,发现了一个比较好的解决方案,就是采用SqlBul ...
- kettle教程---kettle作业调度,根据更新时间增量更新
本文接上一篇,只写到读取日志.在平时工作当中,会遇到这种情况,而且很常见.比如:增量抽取(每隔2个小时抽取截至到上次抽取时间的记录) 本文中会用到作业,先来熟悉下作业的概念 简单地说,一个转换就是一个 ...
- luoguP3531 [POI2012]LIT-Letters
(https://www.luogu.org/problem/P3531) 注意编号 #include<cstdio> #include<algorithm> #include ...
- c# 第30节 类字段与属性
本节内容: 1:字段是什么 2:属性判断字段的安全 3:对属性的解释 1:字段是什么 字段其实在上一节我们就使用过了:再来详细的说他一说 amespace cw { public enum gende ...
- pytorch 创建tensor的几种方法
tensor默认是不求梯度的,对应的requires_grad是False. 1.指定数值初始化 import torch #创建一个tensor,其中shape为[2] tensor=torch.T ...
- 浅谈DFS序
浅谈DFS序 本篇随笔简要讲解一下信息学奥林匹克竞赛中有关树的DFS序的相关内容. DFS序的概念 先来上张图: 树的DFS序,简单来讲就是对树从根开始进行深搜,按搜到的时间顺序把所有节点打上时间戳. ...
- 快速傅立叶变换(FFT)
多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...
- Python apply函数
Python apply函数 1.介绍 apply函数是pandas里面所有函数中自由度最高的函数.该函数如下: DataFrame.apply(func, axis=0, broadcast=Fal ...