iis7发布php网站/快速建站工具
文章目录
- 案例引入
- 原始方案实现
- 实现
- 问题分析
- 介绍
- 基础介绍
- 登场角色
- 案例实现
- 案例一
- 类图
- 实现
- 分析
- 案例二
- 类图
- 实现
- 观察者模式在JDK源码的应用
- 总结
- 文章说明
案例引入
有一个天气预报项目,需求如下:
- 气象站可以将每天测量到的温度、湿度、气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)
- 需要设计开放型API,便于其他第三方也能接入气象站获取数据
- 提供温度、气压、湿度的接口
- 测量数据更新时,要能实时的通知给第三方
原始方案实现
设计一个WeatherData类,类里面的方法如下:
- getTemperature0:获取温度
- getHumidity0:获取湿度
- getPressure0:获取气压
- dataChange0:可以定时(如每十分钟调用一次)调用该方法去气象站更新温度、湿度、气压数据,并主动推送给应用者
实现
【当前天气状况】
package com.atguigu.observer;/*** 显示当前天气情况(可以理解成是气象站的网站)* @author Administrator**/
public class CurrentConditions {/*** 温度*/private float temperature;/*** 气压*/private float pressure;/*** 湿度*/private float humidity;/*** 更新 天气情况,是由WeatherData来调用将最新的数据推送过来* @param temperature* @param pressure* @param humidity*/public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}/*** 显示天气情况*/public void display() {System.out.println("***Today mTemperature: " + temperature + "***");System.out.println("***Today mPressure: " + pressure + "***");System.out.println("***Today mHumidity: " + humidity + "***");}
}
【气象台的天气数据】
package com.atguigu.observer;/*** 类是核心* 1. 包含最新的天气情况信息* 2. 含有 CurrentConditions 对象* 3. 当数据有更新时,就主动的调用CurrentConditions对象的update方法(含 display), 这样他们(接入方)就看到最新的信息* @author Administrator**/
public class WeatherData {private float temperatrue;private float pressure;private float humidity;private CurrentConditions currentConditions;/*** 加入新的第三方* @param currentConditions*/public WeatherData(CurrentConditions currentConditions) {this.currentConditions = currentConditions;}public float getTemperature() {return temperatrue;}public float getPressure() {return pressure;}public float getHumidity() {return humidity;}public void dataChange() {//调用 接入方的 updatecurrentConditions.update(getTemperature(), getPressure(), getHumidity());}/*** 当数据有更新时,就调用 setData* @param temperature* @param pressure* @param humidity*/public void setData(float temperature, float pressure, float humidity) {this.temperatrue = temperature;this.pressure = pressure;this.humidity = humidity;//调用dataChange, 将最新的信息 推送给 接入方 currentConditionsdataChange();}
}
【主类】
package com.atguigu.observer;public class Client {public static void main(String[] args) {//创建接入方 currentConditionsCurrentConditions currentConditions = new CurrentConditions();//创建 WeatherData 并将 接入方 currentConditions 传递到 WeatherData中WeatherData weatherData = new WeatherData(currentConditions);//更新天气情况weatherData.setData(30, 150, 40);//天气情况变化System.out.println("============天气情况变化=============");weatherData.setData(40, 160, 20);}
}
【运行】
***Today mTemperature: 30.0***
***Today mPressure: 150.0***
***Today mHumidity: 40.0***
============天气情况变化=============
***Today mTemperature: 40.0***
***Today mPressure: 160.0***
***Today mHumidity: 20.0***Process finished with exit code 0
问题分析
当添加其他第三方网站时,需要修改WeatherData类,不符合开闭原则,不利于维护
改进:推荐使用观察者模式
介绍
基础介绍
- 观察者模式的工作原理:观察者到观察对象中进行注册,当观察对象的状态发生改变时,就通知已经注册的观察者,观察者可以被从观察对象中移除
登场角色
Subject(观察对象)
:Subject角色定义了注册、删除观察者的方法,还可以声明“获取现在的状态”的方法ConcreteSubject(具体的观察对象)
:当自身状态发生变化后,它会通知所有已经注册的Observer角色Observer(观察者)
:负责接收来自Subject角色状态变化的通知,声明了update方法来接收通知ConcreteObserver(具体的观察者)
:当它的update方法被调用后,会去获取要观察的对象的最新状态
案例实现
案例一
类图
实现
【Subject:观察对象接口】
package com.atguigu.observer.improve;/*** 接口, 让WeatherData 来实现*/
public interface Subject {/*** 观察者注册* @param o*/public void registerObserver(Observer o);/*** 移除观察者* @param o*/public void removeObserver(Observer o);/*** 通知所有观察者*/public void notifyObservers();
}
【Observer:观察者接口】
package com.atguigu.observer.improve;/*** 观察者接口*/
public interface Observer {/*** 更新数据** @param temperature* @param pressure* @param humidity*/public void update(float temperature, float pressure, float humidity);
}
【WeatherData:具体观察对象】
package com.atguigu.observer.improve;import java.util.ArrayList;/*** 类是核心* 1. 包含最新的天气情况信息* 2. 含有 观察者集合,使用ArrayList管理* 3. 当数据有更新时,就主动的调用ArrayList, 通知所有的(接入方)就看到最新的信息** @author Administrator*/
public class WeatherData implements Subject {private float temperature;private float pressure;private float humidity;/*** 观察者集合*/private ArrayList<Observer> observers;/*** 构造方法*/public WeatherData() {// 创建新的集合observers = new ArrayList<Observer>();}public float getTemperature() {return temperature;}public float getPressure() {return pressure;}public float getHumidity() {return humidity;}public void dataChange() {//调用 接入方的 updatenotifyObservers();}//当数据有更新时,就调用 setDatapublic void setData(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;//调用dataChange, 将最新的信息 推送给 接入方 currentConditionsdataChange();}/*** 注册一个观察者* @param o*/@Overridepublic void registerObserver(Observer o) {observers.add(o);}/*** 移除一个观察者* @param o*/@Overridepublic void removeObserver(Observer o) {if (observers.contains(o)) {observers.remove(o);}}/*** 遍历所有的观察者,并通知*/@Overridepublic void notifyObservers() {for (int i = 0; i < observers.size(); i++) {observers.get(i).update(this.temperature, this.pressure, this.humidity);}}
}
【CurrentConditions:具体观察者】
package com.atguigu.observer.improve;public class CurrentConditions implements Observer {/*** 温度*/private float temperature;/*** 气压*/private float pressure;/*** 湿度*/private float humidity;/*** 更新 天气情况,是由 WeatherData 来调用,我使用推送模式** @param temperature* @param pressure* @param humidity*/public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}/*** 显示*/public void display() {System.out.println("***Today mTemperature: " + temperature + "***");System.out.println("***Today mPressure: " + pressure + "***");System.out.println("***Today mHumidity: " + humidity + "***");}
}
【BaiduSite:具体观察者】
package com.atguigu.observer.improve;/*** 百度网站*/
public class BaiduSite implements Observer {private float temperature;private float pressure;private float humidity;/*** 更新天气情况,是由 WeatherData 来调用,我使用推送模式** @param temperature* @param pressure* @param humidity*/public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}/*** 显示*/public void display() {System.out.println("===百度网站====");System.out.println("***百度网站 气温 : " + temperature + "***");System.out.println("***百度网站 气压: " + pressure + "***");System.out.println("***百度网站 湿度: " + humidity + "***");}}
【主类】
package com.atguigu.observer.improve;public class Client {public static void main(String[] args) {//创建一个WeatherDataWeatherData weatherData = new WeatherData();//创建观察者CurrentConditions currentConditions = new CurrentConditions();BaiduSite baiduSite = new BaiduSite();//注册到weatherDataweatherData.registerObserver(currentConditions);weatherData.registerObserver(baiduSite);//测试System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);System.out.println();System.out.println("----- 移除一个观察者 -----");weatherData.removeObserver(currentConditions);//测试System.out.println();System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);}}
【运行】
通知各个注册的观察者, 看看信息
***Today mTemperature: 10.0***
***Today mPressure: 100.0***
***Today mHumidity: 30.3***
===百度网站====
***百度网站 气温 : 10.0***
***百度网站 气压: 100.0***
***百度网站 湿度: 30.3***----- 移除一个观察者 -----通知各个注册的观察者, 看看信息
===百度网站====
***百度网站 气温 : 10.0***
***百度网站 气压: 100.0***
***百度网站 湿度: 30.3***Process finished with exit code 0
分析
- 使用该模式,拓展方便,比如需要新增一个观察者,只需要实现一个具体的观察者类,然后在观察对象中注册即可
案例二
类图
实现
【观察者接口】
package com.atguigu.observer.Sample;public interface Observer {public abstract void update(NumberGenerator generator);
}
【被观察对象抽象类】
package com.atguigu.observer.Sample;import java.util.ArrayList;
import java.util.Iterator;/*** 用来生成数值的抽象类*/
public abstract class NumberGenerator {/*** 保存Observer们*/private ArrayList observers = new ArrayList();/*** 注册Observer** @param observer*/public void addObserver(Observer observer) {observers.add(observer);}/*** 删除Observer** @param observer*/public void deleteObserver(Observer observer) {observers.remove(observer);}/*** 向Observer发送通知*/public void notifyObservers() {Iterator it = observers.iterator();while (it.hasNext()) {Observer o = (Observer) it.next();o.update(this);}}/*** 获取数值** @return*/public abstract int getNumber();/*** 生成数值*/public abstract void execute();
}
【具体的被观察对象】
package com.atguigu.observer.Sample;import java.util.Random;/*** 具体的被观察对象*/
public class RandomNumberGenerator extends NumberGenerator {/*** 随机数生成器*/private Random random = new Random();/*** 当前数值*/private int number;/*** 获取当前数值* @return*/public int getNumber() { return number;}public void execute() {for (int i = 0; i < 20; i++) {// 生成随机数number = random.nextInt(50);// 通知观察者notifyObservers();}}
}
【数值显示观察者】
package com.atguigu.observer.Sample;/*** 使用数字形式显示观察到的数值*/
public class DigitObserver implements Observer {public void update(NumberGenerator generator) {System.out.println("DigitObserver:" + generator.getNumber());try {Thread.sleep(100);} catch (InterruptedException e) {}}
}
【图像显示观察者】
package com.atguigu.observer.Sample;/*** 使用图像显示观察到的数值*/
public class GraphObserver implements Observer {public void update(NumberGenerator generator) {System.out.print("GraphObserver:");int count = generator.getNumber();for (int i = 0; i < count; i++) {System.out.print("*");}System.out.println("");try {Thread.sleep(100);} catch (InterruptedException e) {}}
}
【主类】
package com.atguigu.observer.Sample;public class Main {public static void main(String[] args) {NumberGenerator generator = new RandomNumberGenerator();Observer observer1 = new DigitObserver();Observer observer2 = new GraphObserver();generator.addObserver(observer1);generator.addObserver(observer2);generator.execute();}
}
【运行】
DigitObserver:2
GraphObserver:**
DigitObserver:7
GraphObserver:*******
DigitObserver:6
GraphObserver:******
DigitObserver:26
GraphObserver:**************************
DigitObserver:16
GraphObserver:****************
DigitObserver:6
GraphObserver:******
DigitObserver:28
GraphObserver:****************************
DigitObserver:10
GraphObserver:**********
DigitObserver:6
GraphObserver:******
DigitObserver:10
GraphObserver:**********
DigitObserver:20
GraphObserver:********************
DigitObserver:14
GraphObserver:**************
DigitObserver:21
GraphObserver:*********************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:31
GraphObserver:*******************************
DigitObserver:34
GraphObserver:**********************************
DigitObserver:19
GraphObserver:*******************
DigitObserver:30
GraphObserver:******************************
DigitObserver:0
GraphObserver:
DigitObserver:1
GraphObserver:*Process finished with exit code 0
观察者模式在JDK源码的应用
Observable直接就是类,没有实现Subject接口,直接在类中实现管理Observer的核心方法,当然,可以写更多的子类来集成Observable以便实现更多的操作
总结
- 可替换性强:被观察对象中的观察者集合的观察者类型是Observer角色,可以接收各种各样的具体Observer角色,而且可以统一调用他们的update方法;Observer的update方法接收的数据类型也是Subject,在update方法里面也可以统一调用方法来获取具体被观察对象的属性
- update方法所需要的参数非常灵活,可以自己按照需求来定义
- 观察者模式并非主动去观察,而是被观测对象主动去通知,称为发布——订阅模式可能更加贴切
文章说明
- 本文章为本人学习尚硅谷的学习笔记,文章中大部分内容来源于尚硅谷视频(点击学习尚硅谷相关课程),也有部分内容来自于自己的思考,发布文章是想帮助其他学习的人更方便地整理自己的笔记或者直接通过文章学习相关知识,如有侵权请联系删除,最后对尚硅谷的优质课程表示感谢。
- 本人还同步阅读《图解设计模式》书籍(图解设计模式/(日)结城浩著;杨文轩译–北京:人民邮电出版社,2017.1),进而综合两者的内容,让知识点更加全面
相关文章:

【设计模式——学习笔记】23种设计模式——观察者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)
文章目录 案例引入原始方案实现实现问题分析 介绍基础介绍登场角色 案例实现案例一类图实现分析 案例二类图实现 观察者模式在JDK源码的应用总结文章说明 案例引入 有一个天气预报项目,需求如下: 气象站可以将每天测量到的温度、湿度、气压等等以公告的…...

【奇葩瑞萨-004】RX系列单片机的GPIO初始化
RX系列单片机的GPIO初始化 与IO口相关的寄存器端口(PORT)寄存器端口功能控制(MPC)寄存器MPC.PmnFPS的设置过程MPC寄存器设置注意事项 端口Pmn的初始化不同端口模式下,PORT、MCP寄存器的配置顺序 感想:与STM…...

【Git】Git切换地址
如何切换git代码地址? 1、查看当前远程 url git remote -v执行命令后,可以看见当前有2个URL。 远程 URL 在一般情况下有两个,分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时…...

elementUI点击当前行更改当前行状态(数据更新DOM不更新问题解决)
<template slot-scope"{row,$index}" slot"menu"><el-button v-if"row.editable" type"text" size"small" click"changeStatus(row,$index)">编辑</el-button><el-button v-else type"…...

python爬取阿里巴巴商品页面数据api
以下是使用Python爬取商品页面的示例代码: import requests from bs4 import BeautifulSoup# 定义要爬取的商品链接 url https://www.alibaba.com/product-detail/High-Quality-Custom-Logo-Printing-Black_60802527914.html# 发送请求 response requests.get(ur…...

angular-mat-select 多选 实现按选择顺序排序
mat-select 正常情况下,多选后,已选项是按列表顺序进行排序,如果我想实现按照点击项目的顺序进行排序,我该如何做呢? [参考网址](Angular order of selected option in multiple mat-select - Stack Overflow) sortComparator是Angular Material中mat-select组件的一个属…...

爬虫010_列表高级_添加_append_extend_修改_查询_in_not int_删除_del_pop_remove---python工作笔记029
然后再来看列表操作 首先添加append方法 然后插入,坐标是要插入的下标,右边是插入的内容 看结果 1,2,3,4,5,6 然后这个extend,是逐个插入,放到后边 然后是修改,直接对下标赋值 看结果</...

微服务服务拆分和远程调用
一、服务架构比较 单体架构:简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统 分布式架构:松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目&#x…...

MySQL8.1源码安装与部署
官方文档 https://downloads.mysql.com/archives/community/https://dev.mysql.com/doc/refman/8.1/en/binary-installation.html官方文档源码安装步骤 # Preconfiguration setup $> groupadd mysql $> useradd -r -g mysql -s /bin/false mysql # Beginning of source-b…...

algebraic reconstruction technique(ART)
数值线性代数的Kaczmarz方法被Gordon,Bender,Herman引入至CT重建中,称为ART方法。 A x b Axb Axb A A A为 m n m\times n mn的稀疏矩阵。 A A A的元素 a i j a_{ij} aij表示像素 j j j对射线 i i i投影的贡献。 A A A的行向量 a i T a…...

oracle11g安装
oracle11g安装 安装环境 虚拟机版本:centos7.9 虚拟机ip:192.168.5.144 oracle版本:11g oracle安装包:p13390677_112040_Linux-x86-64_1of7.zip,p13390677_112040_Linux-x86-64_2of7.zip,p13390677_11204…...

网络防御(9)
.一、SSL工作过程是什么? SSL位于应用层和传输层之间,它能够为基于TCP等可靠连接的应用层协议提供安全性保证。SSL协议本身分为两层: 上层为SSL握手协议(SSL handshake protocol)、SSLpassword变化协议(S…...

Spring核心与设计思想
文章目录 Spring是什么?认识Spring IoC容器传统的开发图书管理系统设计可能导致的问题 使用IoC容器 Spring是什么? Spring是一个用于构建企业级应用程序的开源框架,它为Java开发者提供了一种简化和加速应用程序开发的方式。Spring框架提供了…...

【stream的使用】使用stream.filter过滤List对象
Stream初相识 概括讲,可以将Stream流操作分为3种类型: 创建Stream Stream中间处理 终止Steam 每个Stream管道操作类型都包含若干API方法,先列举下各个API方法的功能介绍。 开始管道 主要负责新建一个Stream流,或者基于现有的数组…...

Flink多流处理之connect拼接流
Flink中的拼接流connect的使用其实非常简单,就是leftStream.connect(rightStream)的方式,但是有一点我们需要清楚,使用connect后并不是将两个流给串联起来了,而是将左流和右流建立一个联系,作为一个大的流,并且这个大的流可以使用相同的逻辑处理leftStream和rightStream,也可以…...

对任意类型数都可以排序的函数:qsort函数
之前我们学习过冒泡排序: int main() {int arr[] { 9,7,8,6,5,4,3,2,1,0 };int sz sizeof(arr)/sizeof(arr[0]);int i 0;for (i 0; i < sz-1; i) {int j 0;for (j 0; j < sz-1-i; j) {if (arr[j] > arr[j 1]){int temp 0;temp arr[j];arr[j] ar…...

vue数据更新table内容不更新解决方法
场景: table组件绑定的数据变化时,页面没有重新渲染,常见于子组件中使用table组件 原理: 创建实例时 数组在vue中没有被监听到,属于非响应式数据,数组的下标变化无法监听到 解决方式: <e…...

合宙Air724UG LuatOS-Air script lib API--record
record Table of Contents record record.start(seconds, cbFnc, type, quality, rcdType, format, streamRptLen) record.stop(cbFnc) record.getFilePath() record.getData(offset, len) record.getSize() record.delete() record.exists() record.isBusy() record 模块功能&…...

基于Vgg16和Vgg19深度学习网络的步态识别系统matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 ................................................................ % 设置训练选项options …...

Java分布式微服务3——Docker
文章目录 Docker介绍安装DockerDocker基础操作Docker服务的启动镜像命令容器命令1. 从docker hub去查看Nginx容器的运行命令2. 查看所有容器状态3. 查看容器日志4. 进入Nginx容器执行命令,修改Html内容,添加“Hello World”5. 停止与开始容器6. 删除容器…...

js字符串替换
在JavaScript中,字符串替换 有多种方法,下面介绍其中一些比较常用的方法。 使用replace()方法、 replace()方法用于在字符串中查…...

网络防御(2)
1. 什么是防火墙? 2. 状态防火墙工作原理? 3. 防火墙如何处理双通道协议? 一、什么是防火墙? 防火墙是一种网络安全设备或软件,用于保护计算机网络免受未经授权的访问,并管理网络流量。它作为一个安全边界…...

[RCTF2019]DontEatMe
前言 一道迷宫题,但是输入被加密后使用,迷宫也需要在程序中找出并没有直接输出 分析 反调试 发现有两个比较特殊的地方,随机数和创建了新线程,随机数后面又被重新赋值给覆盖了,暂时不用管,ZwSetInformat…...

6. CSS(三)
目录 一、盒子模型 (一)网页布局的本质 (二)盒子模型组成 (三)边框(border) (四)表格的细线边框 (五)内边距(padding…...

计算机网络—HTTP
这里写目录标题 HTTP是什么HTTP常见状态码HTTP常见字段GET与POST的区别Get和Post是安全和幂等吗PUT幂等,不安全DELETE幂等,不是安全 HTTP缓存技术HTTP缓存实现技术 HTTP1.0优缺点和性能HTTP1.1优缺点和性能HTTP2优缺点和性能HTTP3优缺点和性能HTTP和HTTP…...

Tomcat线程池原理
1. 一个 SpringBoot 项目能同时处理多少请求?tomcat容器, 200 次。 2. 怎么来的? 而点击这些线程,查看其堆栈消息,可以看到 Tomcat、threads、ThreadPoolExecutor 等关键字 基于“短时间内有 200 个请求被立马处理…...

踩坑 视觉SLAM 十四讲第二版 ch13 编译及运行问题
一、安装Geset 库 sudo apt-get install libgtest-dev cd /usr/src/gtest sudo mkdir build cd build sudo cmake .. //一定要以sudo的方式运行,否则没有写入权限 sudo make //这个也一样要以sudo的方式 sudo cp libgtest*.a /usr/local/lib //将生成…...

【设计模式】-装饰器模式
Java 设计模式之装饰器模式 前言 在软件开发中,经常有需求对已有的对象进行功能的扩展,但是传统的继承方式会导致类的数量快速增多,且难以维护。为了解决这个问题,装饰器模式应运而生。 装饰器模式是一种结构型设计模式ÿ…...

七月学习总结
一晃暑期七月份已经结束了,八月份需要做的事情更多。 在成长的路上不断地迷茫,不断地前进。到底才能完成对自己地救赎。 目前想的就是以后走软件开发,往架构方向做,主语言Java或者go,408基础一定要扎实,计…...

Camunda 7.x 系列【6】Spring Boot 集成 Camunda 7.19
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. Camunda Platform Run3. Spring Boot 版本兼容性4. 集成 Spring Boot5. 启动项目…...