一篇文章带你搞懂观察者模式
文章目录
- 观察者模式
- 1、目的
- 2、观察者和被观察者关系
- 3、UML
- 4、代码实现
- 4.1、demo:天气
- 4.2、demo:数值转换
观察者模式
1、目的
观察者模式使得一个对象的状态改变时,已经注册的其它依赖对象能够观察到这一改变。
2、观察者和被观察者关系
对象之间一对多的一种设计方案,被依赖的对象为被观察者,依赖的对象为Observer(观察者)。当被观察者的状态发生变化,所有的依赖对象Observer都将被通知,属于行为型模式。
3、UML
- Subject:通常是由类实现的可观察的接口
- registerObserver():注册观察者
- removeObserver():移除观察者
- notifyObservers():通知注册的所有观察者
- notifyObservers(Observer o):通知具体的观察者
- Observer:观察者是一个由对象实现的接口,根据Subject中的更改接受输入来进行更新。每个观察者都应该实现update方法,该方法通知它们新的状态变化。
- ConcreteSubject:一个实现Subject的类,它处理观察者列表并更新他们的变化。
4、代码实现
4.1、demo:天气
气象站把每天测量到的天气实时推送到第三方
- Subject
package com.lin.observer.demo2;/*** @author linxh*/
public interface Subject {void registerObserver(Observer observer);void removerObserver(Observer observer);void notifyObservers();void notifyObservers(Observer observer);}
- Observer
package com.lin.observer.demo2;/*** @author linxh*/
public interface Observer {void update(float temperature, float pressure, float humidity);
}
- ConcreteSubject
package com.lin.observer.demo2;import java.util.HashSet;
import java.util.Set;/*** @author linxh*/
public class Weather implements Subject {private float temperature;private float pressure;private float humidity;private final Set<Observer> observers;public Weather() {observers = new HashSet<>();}public void setData(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;notifyObservers();}@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removerObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {observers.forEach(o -> o.update(temperature, pressure, humidity));}@Overridepublic void notifyObservers(Observer observer) {observer.update(temperature, pressure, humidity);}
}
- ConcreteObserver
package com.lin.observer.demo2;/*** @author linxh*/
public class Sina implements Observer {private float temperature;private float pressure;private float humidity;@Overridepublic void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}public void display() {System.out.println("新浪天气温度:" + this.temperature);System.out.println("新浪天气压力:" + this.pressure);System.out.println("新浪天气湿度:" + this.humidity);}
}
package com.lin.observer.demo2;/*** @author linxh*/
public class Baidu implements Observer {private float temperature;private float pressure;private float humidity;@Overridepublic void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}public void display() {System.out.println("百度天气温度:" + this.temperature);System.out.println("百度天气压力:" + this.pressure);System.out.println("百度天气湿度:" + this.humidity);}
}
- 测试
package com.lin.observer.demo2;/*** @author linxh*/
public class Client {public static void main(String[] args) {Weather weather = new Weather();Sina sina = new Sina();weather.registerObserver(sina);System.out.println("第一次天气信息");weather.setData(10, 10, 10);Baidu baidu = new Baidu();weather.registerObserver(baidu);System.out.println("第二次天气信息");weather.setData(20,20,20);weather.removerObserver(sina);System.out.println("第三次天气信息");weather.setData(30,30,30);}
}
- 结果
第一次天气信息
新浪天气温度:10.0
新浪天气压力:10.0
新浪天气湿度:10.0
第二次天气信息
百度天气温度:20.0
百度天气压力:20.0
百度天气湿度:20.0
新浪天气温度:20.0
新浪天气压力:20.0
新浪天气湿度:20.0
第三次天气信息
百度天气温度:30.0
百度天气压力:30.0
百度天气湿度:30.0
4.2、demo:数值转换
输入一个输出其二进制、十进制、十六进制
- Subject
package com.lin.observer.demo1;import java.util.ArrayList;
import java.util.List;/*** @author linxh*/
public class Subject {private final List<Observer> observers;private int number;public Subject() {observers = new ArrayList<>();}public void setNumber(int number) {this.number = number;notifyAllObservers();}public int getNumber() {return number;}public void registerObserver(Observer observer) {observers.add(observer);}public void notifyAllObservers() {observers.forEach(Observer::update);}
}
- Observer
package com.lin.observer.demo1;/*** @author linxh*/
public interface Observer {void update();
}
- ConcreteObserver
package com.lin.observer.demo1;/*** @author linxh*/
public class BinaryObserver implements Observer {private final Subject subject;public BinaryObserver(Subject subject) {this.subject = subject;this.subject.registerObserver(this);}@Overridepublic void update() {System.out.println("Binary String:" + Integer.toBinaryString(subject.getNumber()));}
}
package com.lin.observer.demo1;/*** @author linxh*/
public class OctalObserver implements Observer {private final Subject subject;public OctalObserver(Subject subject) {this.subject = subject;this.subject.registerObserver(this);}@Overridepublic void update() {System.out.println("Octal String: " + Integer.toOctalString(subject.getNumber()));}
}
package com.lin.observer.demo1;/*** @author linxh*/
public class HexObserver implements Observer {private final Subject subject;public HexObserver(Subject subject) {this.subject = subject;this.subject.registerObserver(this);}@Overridepublic void update() {System.out.println("Hex String: " + Integer.toHexString(subject.getNumber()));}
}
- 测试
package com.lin.observer.demo1;/*** @author lin* @version V1.0*/
public class Client {public static void main(String[] args) {Subject subject = new Subject();new HexObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First number change: 15");subject.setNumber(15);System.out.println("Second number change: 12");subject.setNumber(12);}
}
- 结果
First number change: 15
Hex String: f
Octal String: 17
Binary String:1111
Second number change: 12
Hex String: c
Octal String: 14
new BinaryObserver(subject);
System.out.println(“First number change: 15”);
subject.setNumber(15);
System.out.println(“Second number change: 12”);
subject.setNumber(12);
}
}
一篇文章带你搞懂观察者模式相关推荐
- 一篇文章带你搞懂网络层(网际层)-- 地址篇
网络层(Network Layer)是OSI模型中的第三层(TCP/IP模型中的网际层),提供路由和寻址的功能,使两终端系统能够互连且决定最佳路径,并具有一定的拥塞控制和流量控制的能力.相当于发送邮件 ...
- 一篇文章带你搞懂微信小程序的开发过程
点击上方"前端进阶学习交流",进行关注 回复"前端"即可获赠前端相关学习资料 今 日 鸡 汤 只解沙场为国死,何须马革裹尸还. 大家好,我进阶学习者. 前言 小 ...
- 谷歌SEO很复杂?一篇文章带你搞懂它(外贸人必读)
这篇文章是对谷歌SEO流程的一个梳理,此文会用通俗易懂的语言告诉你做Google SEO必须知道的常识.建议和谷歌优化的方法思路. 任何关于谷歌SEO的疑问,可到此文⬇️留言,免费咨询: Google ...
- 一篇文章带你搞懂 DEX 文件的结构
From:https://blog.csdn.net/sinat_18268881/article/details/55832757 Dex文件格式详解:https://www.jianshu.com ...
- 一篇文章带你搞懂前端面试技巧及进阶路线
大家好,我是若川.最近有很多朋友给我后台留言: 自己投了不少简历,但是收到的面试邀请却特别少: 好不容易收到了大厂的面试邀请,但由于对面试流程不清楚,准备的特别不充分,结果也挂了: 对于面试官的问题, ...
- 一篇文章带你搞懂慢SQL以及优化的策略
文章目录 一.什么是慢SQL ? 二.为什么要对慢SQL进行优化? 三.数据库性能 1. 最大数据量 2. 最大并发数 3. 查询耗时0.5秒 4. 具体实施 四.数据库表的设计 1. 数据类型 2. ...
- 一篇文章带你搞懂数据链路层
数据链路层,简称链路层.两个主机之间的数据传输,总是在一段一段的链路上面传送的,也就是说,在两个相邻结点之间(主机与路由器之间 或者 两个路由器之间)传送数据是直接传送的(点对点).这时,就需要使用专 ...
- 一篇文章带你搞懂JS对象的自我销毁
在日常的JS组件开发中,往往会有一些较为复杂的DOM操作及事件监听,尤其是在处理UI层面的widgets时候更为明显.常常会花很多精力在对象的init上,而当组件需要被移除时则仅仅是把所在DOM草草的 ...
- 一篇文章带你搞懂 SpringBoot与Swagger整合
https://blog.csdn.net/itguangit/article/details/78978296
- 《PID》一篇文章带你搞懂使用PID
节选自本人博客:https://www.blog.zeeland.cn/archives/pid-learning 本文为笔者参考了网上众多大神的解析之后加上自己的理解整合起来的,因此在内容上部分参考 ...
最新文章
- day16 递归函数
- 网站的安全证书存在安全问题,无继续浏览按钮
- linux虚拟内存 ppt,Linux虚拟内存管理基础v2研究报告.ppt
- PHP计算表达式-栈
- 操作系统04进程同步与通信
- python 百度ocr识别_Python使用百度Ocr识别文字保存CSV
- java web中整合mq_spring-web 集成 rabbitmq
- 优化 Hive ETL 任务(参数篇)
- Docker 系列 _ 01_ 一念缘起
- sqlserver替换特殊字符
- 鸿蒙os系统3.0电脑,华为鸿蒙系统升级指南,速看!
- 可视化布局html5
- java backoff_Java BackOff类代码示例
- 数据库基础(常见面试题)
- Android 短视频编辑开发之摄像头预览实时美颜(三)
- 漏损分析与控制技术——漏损分析技术
- 浅谈response.setHeader()用法
- myEclipse(MyEclipse)下VSS的安装和使用
- python关键字参数必须位于位置参数之前_python关键字参数和位置参数
- web工程的读书笔记