当前位置: 首页 > news >正文

观察者模式

1. 问题背景

现在有三个类:机器类,工人类,订单类

机器类有一个属性叫 isBroken,类型为boolean,其值为false时,代表机器正常,工人和订单都不受影响

但是当其值为true时,工人需要去进行维修,同时订单状态也会设置为异常

也就是说,当机器类的状态变为异常的一瞬间,立马通知订单、工人进行相应的响应,比如说订单状态应该变为异常,工人状态应该变为维修中等等

2. 解决方案

2.1 轮询

在不了解观察者设计模式的时候你可能会想到通过轮询的方式进行,也就是说订单和工人,每10s去查询一次机器的状态,如果机器状态改变,那么就进行相应的业务逻辑

这样一定程度上可以解决问题,但是有几个明显的缺陷

  1. 每10s一次,性能肯定要受到影响

  2. 消息也不及时,根本没办法保证消息及时更新

2.2 硬通知

机器状态的改变,一定有一个函数去修改它的状态,那么我只需要在修改它 is Broken为true的时候,同时进行工人的业务逻辑以及订单的业务逻辑不就好了吗?

这样其实完全可以解决问题,但是也有几个缺陷

  1. 如果你要通知的对象只有工人和订单两个这倒是没问题,两行代码分别调用订单的业务逻辑函数和工人的业务逻辑函数即可,那如果有一万个你要通知的对象怎么办

  2. 耦合性太高,工人的业务逻辑以及订单的业务逻辑,出现在了机器里面,不方便维护,也不可读,甚至不方便修改、维护、扩展

2.3 观察者模式

观察者模式是一种通过发布-订阅的方式,解耦了被观察者(机器类)与观察者(工人类和订单类)之间的关系,使得一个对象(机器类的is Broken)状态变化时,可以自动通知所有需要关注这个变化的类(工人类和订单类)进行相应的更新或处理。

观察者模式的关键在于将通知机制从具体的业务逻辑中分离出来,这样当机器的 isBroken 状态变化时,机器类本身不需要知道如何处理工人和订单的逻辑,只需要通知工人类和订单类机器状态改变了,然后他们自己执行自己的业务逻辑。

3. 手搓代码环节

3.1 代码结构

image.png

3.2 Subject

主题是Machine类的原型,任何一个需要通知其他类进行变化的都需要以上三个方法,所以提出来成为接口,分别是添加观察者,移除观察者,通知所有观察者

package subject;import observer.Observer;public interface Subject {void addObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}

3.3 Machine

Machine继承上面的主题,并且实现了三个接口,并且有自己的属性isBroken,并提供了get、set方法

package subject;import observer.Observer;import java.util.ArrayList;
import java.util.List;public class Machine implements Subject {private final List<Observer> observers = new ArrayList<>();private boolean isBroken = false;@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.receiveNotification();}}public void setBroken(Boolean isBroken)  {this.isBroken = isBroken;if (isBroken) {notifyObservers();}}public boolean getIsBroken() {return isBroken;}
}

3.3 Observe

每个观察者接受到消息发生变化以后,都需要处理自己的业务逻辑,所以提出来成为方法

package observer;public interface Observer {void receiveNotification();
}

3.4 Worker

package observer;import subject.Machine;public class Worker implements Observer {private Machine machine;public Worker(Machine machine) {this.machine = machine;machine.addObserver(this);}@Overridepublic void receiveNotification() {System.out.println("工人要去维修机器咯");}
}

3.5 Order

package observer;import subject.Machine;public class Order implements Observer {private Machine machine;public Order(Machine machine) {this.machine = machine;machine.addObserver(this);}@Overridepublic void receiveNotification() {System.out.println("订单状态异常咯");}
}

3.6 Main

package app;import observer.Order;
import observer.Worker;
import subject.Machine;public class Main {public static void main(String[] args) {// 创建机器、工人和订单对象Machine machine = new Machine();Worker worker = new Worker(machine);Order order = new Order(machine);// 模拟机器正常运行for (int i = 1; i <= 10; i++) {System.out.println(machine.getIsBroken());}System.out.println("机器损坏");machine.setBroken(true);  // 机器损坏,工人和订单会被通知并作出反应}
}

4. 总结

运行截图

image.png

http://www.lqws.cn/news/591643.html

相关文章:

  • 新版本 Spring Data Jpa + QueryDSL 使用教程
  • TensorFlow源码深度阅读指南
  • 【科研绘图系列】基于R语言的复杂热图绘制教程:环境因素与染色体效应的可视化
  • C#程序设计简介
  • 9-2 MySQL 分析查询语句:EXPLAIN(详细说明)
  • Milvus docker-compose 部署
  • 从苹果事件看 ARM PC市场的未来走向
  • 2025年Java后端开发岗面试的高频项目场景题 + 八股文(100w字)
  • SAFNet:一种基于CNN的轻量化故障诊断模型
  • 【os】标准库
  • Rust 学习笔记:比较数值
  • 分布式锁——学习流程
  • 设计模式精讲 Day 20:状态模式(State Pattern)
  • 从零到一搭建远程图像生成系统:Stable Diffusion 3.5+内网穿透技术深度实战
  • 深入解析NumPy的核心函数np.array()
  • Linux 终止进程
  • 企业级应用技术-ELK日志分析系统
  • Text2SQL主流实现方案
  • js代码09
  • matlab/Simulink-全套50个汽车性能建模与仿真源码模型9
  • Next.js 安装使用教程
  • UniApp完全支持快应用QUICKAPP-以及如何采用 Uni 模式开发发行快应用优雅草卓伊凡
  • Spring Boot 启动加载执行链路分析
  • 基于Socketserver+ThreadPoolExecutor+Thread构造的TCP网络实时通信程序
  • 启用不安全的HTTP方法
  • 遥感影像岩性分类:基于CNN与CNN-EL集成学习的深度学习方法
  • 二十八、【环境管理篇】灵活应对:多测试环境配置与切换
  • Prompt生成指南
  • Gin 中间件详解与实践
  • AT6558R-5N32介绍