必须做作业三:Network-Monitor观察者模式解析

article/2025/10/14 7:28:59

  一、总述

  观察者模式,由观察者和被观察对象组成,java已经提供了相关类供我们开发者调用!

  当数据变化时,Observable会通知集合里的所有观察者对象!具体在数据变化后,app调用Observable的notifyObservers方法,那么 集合里的所有Observer的update()会被执行!

  设计其实很简单,当数据要发生改变时,被观察者observable将会调用相关方法通知观察者对象集合里的所有观察者,然后集合里所有的observer再调用自己的方法更新自己的状态。

  其中observe和observable类直接是调用java函数

  1、观察者模式类图:

  

  2、github地址:

  https://github.com/shonegg/NetMonitor

  观察者与被观察者来自JAVA自带的类。

  具体被观察者:https://github.com/shonegg/NetMonitor/blob/master/library/src/main/java/com/net/framework/NetObservable.java

  具体观察者:https://github.com/shonegg/NetMonitor/blob/master/library/src/main/java/com/net/framework/NetObserver.java

 

二、观察者模式具体分析

  1、被观察者(Observable)

  在github里作者直接用import 导入了observable类,所以我在官方文档里找到了observable类的代码(由于代码过长,删掉了部分注释)

package java.util;

public class Observable {private boolean changed = false;private Vector obs;/** Construct an Observable with zero Observers. */public Observable() {obs = new Vector();}public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}}public synchronized void deleteObserver(Observer o) {obs.removeElement(o);}public void notifyObservers() {notifyObservers(null);}public void notifyObservers(Object arg) {/** a temporary array buffer, used as a snapshot of the state of* current Observers.*/Object[] arrLocal;synchronized (this) {if (!changed)return;arrLocal = obs.toArray();clearChanged();}for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);}/*** Clears the observer list so that this object no longer has any observers.*/public synchronized void deleteObservers() {obs.removeAllElements();}protected synchronized void setChanged() {changed = true;}protected synchronized void clearChanged() {changed = false;}public synchronized boolean hasChanged() {return changed;}/*** Returns the number of observers of this <tt>Observable</tt> object.** @return  the number of observers of this object.*/public synchronized int countObservers() {return obs.size();}
}<span style="font-size:18px;">
</span>
  • 我们可以看出,被观察者类给出了添加观察者对象、删除观察者对象、通知观察者对象等方法,被观察者对象即可直接继承,重写一些方法。

 

  2.具体被观察者 (NetObservable)

package com.net.framework;/*** Author   Shone* Date     04/07/16.* Github   https://github.com/shonegg*/import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;import java.util.Observable;
import java.util.Observer;public class NetObservable extends Observable {private Context context;public NetObservable(Context context) {super();this.context = context;}@Overridepublic void addObserver(Observer observer) {try {super.addObserver(observer);NetworkInfo networkInfo = Network.getCurrentActiveNetwork(this.context);if (networkInfo != null) {if (!networkInfo.isAvailable()) {observer.update(this, new NetObserver.NetAction(false, false, Network.getSubType(context)));return;}if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {observer.update(this, new NetObserver.NetAction(true, true, Network.getSubType(context)));return;}observer.update(this, new NetObserver.NetAction(true, false, Network.getSubType(context)));return;}observer.update(this, new NetObserver.NetAction(false, false, Network.getSubType(context)));} catch (Exception e) {e.printStackTrace();}}@Overridepublic void notifyObservers(Object data) {try {this.setChanged();super.notifyObservers(data);} catch (Exception e) {e.printStackTrace();}}
}
  • 这里setChanged()是关键,她将内部标志置为真changed = true,下面是通知父方法
  • 以上的被观察者对象重新写了addObsever方法,这个方法是为了在增加观察者的时候,马上得到观察者当前的网络状态。
  • 该被观察者对象还重新写了notifyObsevers的方法(通过调用this.setChanged(),再调用其父类被观察者类中的通知方法,setChanged()是用来设定被观察者的状态已经被改变,改变之后,notifyObserver()方法会通知所要订阅主题物件的观察者,调用其 update()方法。)
3、观察者:observer
  • 这部分也是直接import自带库中的observer类,这里直接贴出来官方文档(删掉部分注释)
  • 我们可以看出,类中只包含了update方法,当收到被观察者网络发生改变调用notifyobservers方法时,用来更新观察者的网络状态。
/** Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.**/
package java.util;*/
public interface Observer {
void update(Observable o, Object arg);
}

 

4、具体观察者:

package com.net.framework;/*** Author   Shone* Date     04/07/16.* Github   https://github.com/shonegg*/import java.util.Observable;
import java.util.Observer;public abstract class NetObserver implements Observer {public static class NetAction {private boolean isAvailable;private boolean isWifi;private Network.Type type;public NetAction(boolean isAvailable, boolean isWifi, Network.Type type) {super();this.isAvailable = isAvailable;this.isWifi = isWifi;this.type = type;}public boolean isAvailable() {return this.isAvailable;}public Network.Type getType() {return type;}public void setType(Network.Type type) {this.type = type;}public boolean isWifi() {return this.isWifi;}}public abstract void notify(NetAction action);@Overridepublic void update(Observable observable, Object data) {this.notify(((NetAction) data));}
}
  • 观察者对象NetAction中有一个枚举类成员Network.Type,详细描述了是哪一种网络:
  • 观察者对象扩展了netaction方法,用来保存被观察者传下来的具体消息(如网络种类、wifi等)
观察者对象扩展了一个新的notify方法,重写Update的时候调用了该方法,传递的参数是网络状态改变的具体消息(netaction),因为观察者对象并不用关心其父类观察者类的情况,只是接口得到具体的消息就可以了
三、应用场景与好处:
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。在我们的这个网络监控中,观察者依赖于被观察者。
  • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。当被观察者的数据要发生改变时,对应的观察者的数据也要改变,这个时候只要将被观察者里的观察者集合都改变了就可以了
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。
  • 在观察者和被观察者之间建立了一个耦合,对于被观察者来说,他只对它的观察者集合负责,然后具体的网络改变都是通过接口传递,只需要改变setchange()与Notifyobservers()即可,剩下的不需要被观察者在意。被观察者也不需要知道观察者都有些谁。
  • 而对于观察者而言,它不需要知道被观察者的情况,只需要知道接口传下来的netaciton(具体动作如网络状态、WiFi改变),执行自己的update()更新自己的状态即可。
  • 它们没有紧密的耦合,可以属于不同的抽象化层次
  • 一旦数据改变,支持广播通信很适合被观察者向每一个观察者广播改变网络状态的通知。

转载于:https://www.cnblogs.com/liuyuhao/p/9826375.html


http://chatgpt.dhexx.cn/article/VS6aVR8q.shtml

相关文章

n个数 全排列算法

全排列 给定N个数&#xff0c;如 [1,2,3,4,5]&#xff0c;获取它的全排列 经典交换算法 核心思路是交换 #include<stdio.h> void swap(int* a, int* b){int temp *a;*a *b;*b temp; } //int a[] { 1,2,3,4}; //sort(a, 0, 4); void sort(int* a, int k, int m){…

全排列算法(C语言)

全排列算法&#xff08;C语言&#xff09; 思路图形理解树结构 代码 思路 图形理解 我看先看一下从1–4的全排列&#xff0c;如下&#xff1a; &#xff08;1&#xff09;就整体排列而言可以分为四组&#xff0c;分别是以1打头的&#xff0c;以2打头的&#xff0c;以3打头的&a…

全排列算法(无重复数字全排列/有重复数字全排列)/ 组合算法/ 求子集算法

写在前面全排列1 无重复数字全排列1.1 紫书版本1.2 回溯法 2 有重复数字全排列 复盘易错点&#xff08;可跳过&#xff09; 写在前面 很久很久以前就想写的一篇博客&#xff0c;因为懒一直没开工&#xff0c;但是学习全排列算法算是我对递归理解的转折点&#xff0c;感觉很有意…

全排列算法的全面解析

概述 对数组进行全排列是一个比较常见问题&#xff0c;如果是一个比较喜欢考算法的公司&#xff08;貌似一些大公司都比较喜欢考算法&#xff09;&#xff0c;那么估计就会考察应聘者这个全排列的问题了&#xff08;就算不让你编写完整代码&#xff0c;也会让你描述大致的思路&…

【算法】——全排列算法讲解

前言&#xff1a; 今天&#xff0c;我给大家讲解的是关于全排列算。我会从三个方面去进行展开&#xff1a; 首先&#xff0c;我会给大家分析关于全排列算法的思想和定义&#xff1b;紧接着通过手动实现出一个全排列代码来带大家见见是怎么实现的&#xff1b;最后我会给出两道题…

算法 | 全排列问题(图文详解)

目录 一.全排列的定义 1.什么是全排列 2.例子 二.code 三.分析 一.全排列的定义 1.什么是全排列 从n个不同元素中任取m&#xff08;m≤n&#xff09;个元素&#xff0c;按照一定的顺序排列起来&#xff0c;叫做从n个不同元素中取出m个元素的一个排列。当mn时所有的排列情…

全排列算法思路解析

1.全排列的定义和公式&#xff1a; 从n个数中选取m&#xff08;m<n&#xff09;个数按照一定的顺序进行排成一个列&#xff0c;叫作从n个元素中取m个元素的一个排列。由排列的定义&#xff0c;显然不同的顺序是一个不同的排列。从n个元素中取m个元素的所有排列的个数&#…

全排列算法

全排列的概念 排列 从n个数中选取m&#xff08;m<n&#xff09;个数按照一定的顺序进行排成一个列&#xff0c;叫作从n个元素中取m个元素的一个排列。不同的顺序是一个不同的排列。从n个元素中取m个元素的所有排列的个数&#xff0c;称为排列数&#xff08;几种排法&#…

激活JRebel

生成新的 GUID 将生成的GUID 粘贴到此处 https://jrebel.qekang.com/ 如&#xff1a; https://jrebel.qekang.com/cf0c9d95-c31f-4e75-bc5a-146291b8bb71

JRebelXRebel的配置和使用(进阶篇)

JRebel&XRebel的配置和使用 嘚吧嘚设置JRebel快捷键XRebel使用 嘚吧嘚 之前简单介绍了JRebel&XRebel的安装和使用&#xff0c;不了解的朋友可以补补课哈&#x1f606;。 JRebel&XRebel这款插件不仅仅可以用来热部署&#xff0c;所以继续分享一下这款插件的相关使…

IDEA热部署JRebel插件激活教程

JRebel简介 JRebel是一款实现热部署的开发工具&#xff0c;它可以允许你在启动程序时修改java代码直接进行编译生效&#xff0c;无须手动重启。热部署的实现会为你节省了大量重启时间&#xff0c;明显提高个人开发效率。 安装JReable 同其它插件安装一样&#xff0c;请按照以…

Idea热部署插件JRebel+XRebel

1、下载地址&#xff1a;https://plugins.jetbrains.com/plugin/4441-jrebel-and-xrebel/versions 保险起见这里建议下载2022.4.1版本&#xff0c;否则容易出现JRebel LS client not configured的问题&#xff0c;如果你已经出现了&#xff0c;可以参考 https://blog.csdn.ne…

JRebel 热部署

前言 Jrebel 可快速实现热部署&#xff0c;节省了大量重启时间&#xff0c;提高了个人开发效率。 IDEA上原生是不支持热部署的&#xff0c;一般更新了 Java 文件后要手动重启 Tomcat 服务器&#xff0c;才能生效&#xff0c;浪费时间浪费生命&#xff0c;目前对于idea热部署最…

IDEA热部署插件JRebel使用

JRebel安装与激活 JRebel 使用 此时已经安装好并已激活&#xff0c;我们使用 JRebel debug的时候&#xff0c;修改代码&#xff0c;不能实现热部署&#xff0c;因此还需要设置其他地方 1.项目自动编译 设置 compiler.automake.allow.when.app.running ctrlshiftA 或者 help->…

IDEA插件-热部署:JRebel

一、摘要 springboot项目开发过程中通常修改了某分部代码需要重启服务才能生效。通过JRebel插件可以实现热部署&#xff0c;避免了频繁重启服务。 JRebel是一套JavaEE开发工具。 Jrebel 可快速实现热部署&#xff0c;节省了大量重启时间&#xff0c;提高了个人开发效率。 二、…

Jrebel安装使用教程 及 Jrebel 4.2版本激活失效的处理(超简洁明了)

写在前面&#xff1a;不小心更新了Jrebel插件导致插件用不了qwq&#xff0c;经过查阅多方面的资料总结出了解决这个问题的方法&#xff0c;现分享给大家~ &#xff08;如果原本没安装JRebel插件请直接从第三步开始看~&#xff09; 第一步&#xff1a;删除4.2版本 先在Plugins…

JRebel插件热部署快速入门教程

文章目录 引入插件安装插件激活打开激活窗口激活插件 插件使用设置项目热更新热更新说明演示热更新 引入 视频讲解JRebel安装、使用、部署 Jrebel能够非常方便的帮助我们进行项目的热更新&#xff0c;尤其是前端也嵌在后端工程中的单体项目&#xff0c;热更新能减少一半的开发…

JRebel插件使用详解

JRebel插件安装与使用图文教程 JRebel是一款JVM插件&#xff0c;它使得Java代码修改后不用重启系统&#xff0c;立即生效。IDEA上原生是不支持热部署的&#xff0c;一般更新了 Java 文件后要手动重启 Tomcat 服务器&#xff0c;才能生效&#xff0c;浪费时间浪费生命。 目前对…

javaweb开发,提高效率利器——JRebel

JRebel用了有一段时间了&#xff0c;发现确实好用&#xff0c;节省了很多不必要的时间&#xff0c;提高了开发效率。在这里记录一下他的安装和使用过程&#xff0c;希望能帮助到有需要的人。 官网&#xff1a;https://www.jrebel.com/ 一、JRebel简介 jrebel是国外公司perfo…

JRebel 和 XRebel 激活

1&#xff1a;JRebel 和 XRebel的作用 JRebel&#xff1a;修改完代码&#xff0c;不想重启服务&#xff0c;就使想代码生效。 XRebel&#xff1a;请求中&#xff0c;各个部分代码性能监控。例如&#xff1a;方法执行时间&#xff0c;出现的异常&#xff0c;SQL执行时间&#x…