观察者模式的引出和问题分析 | 学习笔记

简介: 快速学习观察者模式的引出和问题分析

开发者学堂课程【Scala 核心编程 - 进阶观察者模式的引出和问题分析学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/610/detail/9140


观察者模式的引出和问题分析


内容介绍

一、简介

二、普通方案

三、总结

一、简介

observe 及观察者模式是开发中使用较多的一种模式,尤其是在spark中会有模式的身影,由项目的需求引出,首先设计项目称为气象站项目,项目要求就是气象站每天可以把测到的温度、湿度、气压以公告的形式发布出去(比如发到自己的网站)。

打开新浪网,搜狐网,或者是腾讯网都有天气预报,也就是开放了个接口,注册之后就可以有最新的信息了。

需要设计开放的 API,便于其它第三方公司,能接入到气象站,获取信息。提供温度,气压和湿度的接口,测量数据更新时,要能实时的通知给第三方,这是项目的需求。气象站的各个数据要给第三方发过去。

首先要去设计 WeatherData 类,通过对气象站项目的分析,类提供了一系列的方法,得到温度,湿度气压和数据变化。因为数据是实时变化的,例如每隔1小时改一次,或者每隔一段时间更新最新数据,通过GET方法,可以让第三方接入获取相关信息,当数据有更新时,气象站通过dataChange()去更新数据,当第三方再次获取时,就能得到最新数据,当然可以推送。

第一种方式就是气象站有一个程序,每隔一定时间去调用 dataChange(),执行之后,本地的数据就更新了,更新过后,第三方去调 get()方法时,就拥有了最新的温度、湿度。如果直接推送,就必须得知道对方的地址,例如jsp,虽然也可以更新它,但是就要求维护量很大,以上就设计了 WeatherData(),也就是气象站的代码。

先是第一个方案:

image.png可以暂时把 currentconditions 理解成是气象站自己的网站,也可以理解成搜狐、腾讯的当前的天气情况。WeatherData主动调用update(),数据就更新了。只要是注册了,就能够接收,相当于是推送的一种机制,开始写代码,先是普通方案。


二、普通方案

以下为代码:

class CurrentConditions {

private var mTemperature: Float = _

private var mPressure: Float = _

private var mHumidity: Float = _

def display()={

println(“***Today mTemperature: " + mTemperature+ "***")

printin("***Today mPressure: " +mPressure +“***")

printIn("***Today mHumidity: " + mHumidity +"***")

}def update(mTemperature:Float,mPressure:FloatmHumidity: Float)= {

this.mTemperature = mTemperature

this.mPressure = mPressure

this.mHumidity = mHumidity

display()}}

class WeatherData{

private var mTemperatrue: Float =_

private var mPressure: Float = _

private var mHumidity: Float=_

private var mCurrentConditions: CurrentConditions =_

def this(mCurrentConditions: CurrentConditions){

this

this.mCurrentConditions = mcurrentConditions

}

def getTemperature()= {

mTemperatrue}

def getPressure()={

imPressure}

def getHumidity()={

imHumidity }

def dataChange(={

mcurrentConditions.update(getTemperature(),getPressure(),getHumidity())}def setData(mTemperature: Float,mPressure: Float, mHumidity: Float) {=

this.mTemperatrue = mTemperature

this.mPressure = mPressure

this.mHumidity = mHumidity

dataChange()

}}

设计流程如下:

首先先写WeatherData,新建包observer,包中做本地的方案,然后新建本地的internetview。然后写类,类就称为weatherData,类可以理解成是气象局维护的提供天气情况的核心

数据类:

class WeatherData{

private var mTemperatrue: Float =_

private var mPressure: Float = _

private var mHumidity: Float=_

private var mCurrentConditions: CurrentConditions =_

def this(mCurrentConditions: CurrentConditions){

this

this.mCurrentConditions = mcurrentConditions

}

def getTemperature()= {

mTemperatrue}

def getPressure()={

imPressure}

def getHumidity()={

imHumidity }

def dataChange(={

mcurrentConditions.update(getTemperature(),getPressure(),getHumidity())}def setData(mTemperature: Float,mPressure: Float, mHumidity: Float) {=

this.mTemperatrue = mTemperature

this.mPressure = mPressure

this.mHumidity = mHumidity

dataChange()

}}

解释如下:

private var mTemperatrue: Float =_//温度

private var mPressure: Float=_ //气压

private var mHumidity: Float=_//湿度

以下就是气象局的天气公告版:

private var mCurrentCondition: CurrentCondition=_

之后构造 weather 对象时,将 Condition 传入。

detData 就是设置最新的天气情况的函数或者方法:def setData(mTemperature: Float,mPressure: Float, mHumidity: Float) {=

this.mTemperatrue = mTemperature

this.mPressure = mPressure

this.mHumidity = mHumidity

dataChange()

}}

发布最新的天气情况,先把这些信息交给mTemperatrue、mPressure、mHumidity这三个属性,然后调用datachange()来修改公告版的最新数据,调的是公告版的update()方法。

相当于将最新数据推送给公告版:

def dataChange(={mcurrentConditions.date(getTemperature(),getPressure(),getHumidity())

}

把信息推出之后调用接口,该类称为CurrentConditions,也就是气象局的天气公告版。当气象局的核心在调方法时,先更新天气公告版的最新数据,然后显示:

def display()={

println(“***气象局的天气公告板Today mTemperature: " + mTemperature+ "***")

printin("***气象局的天气公告板Today mPressure: " +mPressure +“***")

printIn("***气象局的天气公告板Today mHumidity: " + mHumidity +"***")

}

可以理解为登陆了中央气象局的网站,就有信息了。

用internetweather类来测试:

object InternetWeather{

def main(args: Array[String]): Unit = {

//创建个月气象局的天气公告板

val mCurrentConditions = new CurrentConditions()

val mWeatherData = new WeatherData(mCurrentConditions)

//比如天气情况交化

mveatherData.setData(30,150,40)

}}

首先先创建天气公告版,然后再创建weatherData,并将公告版设置,相当于更新数据,例如天气变化,设置了最新数据。

相当于通知天气公报版去更新数据,然后去调自己的update,然后在diaplay出来。

相当于数据变化先更新自己的,更新完后,就去通知天气公告版更新数据。

运行之后显示今天的天气是30度,压力4度。以上是第一个方案,可以使用,但是会增加对代码的维护工作。核心在currentconditions,currentconditions中维护了当前公告版,如果不是天气局的公告版,还有腾讯的公告版,构建的时候把腾讯的传入是可以的,但是需要重写一遍。显然这样不好,因为当第三方公司要获取数据的时候, 不利于动态的加入,基本上破坏了ocp原则,而且不利于维护。


三、总结

先做了分析,根据需求设计weatherdata类,以下为说明:

1.通过getXx方法,可以让第三方公司接入,并得到相关信息;

2.当数据有更新时,气象站通过调用dataChange()去更新数据,当第三方再次获取时,就能得到最新数据,当然也可以推送。

image.png

设计完后,得出第一种最普通的方案,示意图:

image.png

以上是第一个普通的方案的分析,得出结论:普通方案维护量很大,第三方获取数据问题,无法动态的添加,同时违反了ocp的原则。

相关文章
|
2天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
256 116
|
17天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
11天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
651 221
|
4天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
304 27
Meta SAM3开源:让图像分割,听懂你的话
|
9天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1486 157
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
886 61
|
6天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
284 139