当前位置:网站首页>观察者模式-数据池
观察者模式-数据池
2022-08-10 05:36:00 【yeah_you_are】
一、描述
当对象间存在一对多关系时,则适合使用观察者模式(Observer Pattern)。当一个对象的装态被改变时,则应该通知它的观察者对象,这就是观察者模式。
二、代码实现
被观察者类
public class Subject {
private int status;
private List<Observer> observers = new ArrayList<>();
/** 添加观察者对象 */
public void attach(Observer observer) {
this.observers.add(observer);
}
/** 通知所有观察者对象 */
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
/** 改变状态 */
public void setStatus(int status) {
//状态变化
this.status = status;
System.out.println("状态改变!");
//通知观察者
this.notifyAllObservers();
}
}
观察者抽象类
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
观察者类
public class SubjectObserver extends Observer {
public SubjectObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("被观察者对象subject状态发生变化!");
}
}
测试demo
public class Test {
public static void main(String[] args) {
Subject subject = new Subject();
SubjectObserver observer = new SubjectObserver(subject);
subject.setStatus(1);
}
}
运行结果
三、延伸思考-数据池(生产者与消费者)
生产者与消费者的关系在我们日常生活中非常的普遍,一家超市算是产品池(数据池),我们大众会去消费购买产品,属于消费者,当产品余量不足时会通知供货商发送新的产品过来,供货商就类似于生产者(当然这中间可能有中间商赚差价),一个生产与消费的关系边构建起来了。参考观察者模式,可以给数据池两个身份的观察者,一个是生产者,一个是消费者,代码如下:
数据池
public class DataPool<T> {
private BlockingQueue<T> dataPool ;
private final int MAX_SIZE;
//生产者
private DataPoolObserver producer;
//消费者
private DataPoolObserver consumer;
public DataPool(int MAX_SIZE) {
this.dataPool = new ArrayBlockingQueue<>(MAX_SIZE);
this.MAX_SIZE = MAX_SIZE;
}
/** 添加生产者 */
public void setProducer(DataPoolObserver producer) {
this.producer = producer;
}
/** 添加消费者 */
public void setConsumer(DataPoolObserver consumer) {
this.consumer = consumer;
}
/** 添加数据 */
public void add(T t) {
this.dataPool.add(t);
if (this.consumer != null) {
this.consumer.update();
}
}
/** 移除数据 */
public T get() {
//余量不足,通知生产者
if (this.dataPool.size() < 0.2 * this.MAX_SIZE && this.producer != null) {
this.producer.update();
}
if (this.dataPool.size() > 0) {
return this.dataPool.poll();
}
return null;
}
}
观察者抽象类
public abstract class DataPoolObserver<T> {
protected DataPool<T> dataPool;
public abstract void update();
}
生产者类
public class Producer extends DataPoolObserver<String> {
public Producer(DataPool<String> dataPool) {
this.dataPool = dataPool;
this.dataPool.setProducer(this);
}
/** 生产 */
public void run() {
System.out.println("生产了一个产品!");
this.dataPool.add("产品");
}
@Override
public void update() {
this.run();
}
}
消费者类
public class Consumer extends DataPoolObserver<String> {
public Consumer(DataPool<String> dataPool) {
this.dataPool = dataPool;
this.dataPool.setConsumer(this);
}
/** 消费 */
public void run() {
System.out.println("消费了一个产品!");
this.dataPool.get();
}
@Override
public void update() {
run();
}
}
测试类
public class Test {
public static void main(String[] args) {
DataPool<String> dataPool = new DataPool<>(20);
Producer producer = new Producer(dataPool);
observerPattern.Consumer consumer = new observerPattern.Consumer(dataPool);
producer.run();
}
}
运行结果
这样就实现了一个生产与消费的关系,如果生产者和消费者都实现Runnable接口,就可以使用线程实现异步的生产和消费关系,更加灵活。这样的设计可以给数据传输处理提供便利。
边栏推荐
- LeetCode Interview Question 17.14 Minimum k Number (Moderate)
- STM32单片机LORA无线远程火灾报警监控系统DS18B20MQ2火焰检测
- 浅谈游戏中3种常用阴影渲染技术(1):平面阴影
- markdown使用技巧
- 酸回收工艺原理
- The way for programmers to make money from a sideline business and increase their monthly income by 20K
- Unity中实现Animation Clip动画片段的倒播(该案例可以防止动画延迟)
- 以STM32F103C6TA为例通过配置CubeMX实现GPIO输出完成点灯实例
- 51单片机教室人数进出统计检测数码管显示装置红外传感器
- 51单片机AD590温度测量ADC0832运放2.73V减法电压变换
猜你喜欢
Convolutional Neural Network (CNN) for mnist handwritten digit recognition
ASP.NET连接SQL Server的步骤
LeetCode 938. Range Sum of Binary Search Trees (Simple)
51单片机BH1750智能补光灯台灯光强光照恒流源LED控制系统
Tensorflow 2.0 使用流程详解
每日刷题(day02)——leetcode 622. 设计循环队列
【从零设计 LaTex 模板】1. 一些基础知识
LruCache与DiskLruCache结合简单实现ImageLoader
C陷阱与缺陷 个人阅读笔记
Pytorch配置与实战--Tips
随机推荐
STM32F407ZG 串口通信+固定帧头帧尾传输数据帧
【fiddler2】使用fiddler mock response 数据
Unity中采用二进制存档与读档
从交换两数据值看指针的使用(c语言实现)
最简单的字符设备驱动
LeetCode 1720. Decoding XORed Arrays (Simple)
51单片机AD590温度测量ADC0832运放2.73V减法电压变换
通过adb devices命令在控制台显示企业级PicoNeo3设备号
过大数组导致爆栈的解决方法记录(堆栈)
mysql分组排序并取各分组前几个数据
详解 Hough 变换(下)圆形检测
clickhouse出现数据重复问题
The way for programmers to make money from a sideline business and increase their monthly income by 20K
二次元卡通渲染之描边
51单片机教室人数进出统计检测数码管显示装置红外传感器
Unity中暂停、继续播放、杀死、正放、倒放Dotween动画
【C语言】结构体变量学习笔记1
I don't like my code
酸回收工艺原理
Unity中Xml简介以及通过脚本读取Xml文本中的内容