观察者模式来解决气象局项目 | 学习笔记

简介: 快速学习观察者模式来解决气象局项目

开发者学堂课程【Scala 核心编程 - 进阶观察者模式来解决气象局项目学习笔记,与课程紧密连接,让用户快速学习知识。

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


观察者模式来解决气象局项目


内容介绍

一、原理

二、流程

三、代码

四、扩展


一、原理

普通方案违反了 OCP 原则,所以可以使用观察者模式。观察者模式类似于像订牛奶的业务,假设有个牛奶站,牛奶站把它认为 Subject,用户就是 observer,牛奶站是一,而用户有很多,类似于有很多第三方,但是的气象局只有一个,牛奶中是一个被别人观察的,Observer 是观察者,对于 Subject 来说,可以登记移除或通知就像有一个用户,要去订牛奶,先到牛奶店通知准备订牛奶,牛奶处就先包起来,例如用户是张三,等牛奶到了,牛奶站就把信息推过来,如果不想继续订阅,直接移除即可。

这种逻辑特别适合订阅模式,这种方式在 spark 中用的非常多,而且将来有大量设计思想在中。这些模式不是提出来的,这些模式早在设计者模式中就有观点。关键就是牛奶站应该至少要提供3个方法:

image.png

一是 registerobserver,就是注册;

二是 removeobserver,就是移除,针对于取消订阅;

三是 notifyobservers,如果牛奶站有变化,用户类似于第三方,就调用notifyobservers,通知所有的注册用户 ,根据不同的需求,可以更新数据让用户来取,也可以推送,目前相当于直接实时推送。

对于subject来说,会定义一个接口 ,其中要有3个方法,具体的subject来实现,另外一个就是observer,observer 中最核心的一个方法就是update(),观察者的update()是给subject使用的,例如天气发生变化,想把信息告诉QQ,腾讯公司,就要通过接口,要求所有的接入者必须实现方法,类似于去牛奶站订牛奶,需要给地址,观察者模式也就是对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为 Observer,subject 通知 Observer变化,比如这里的奶站是Subject,是1的一方。用户是 Observer,是多的一方,以上为原理。


二、流程

观察者模式,适合对象之间的多对一的关系,subject 通知 observer 的变化。

设计类图:

image.png

subject 是个接口,但是应该写成 trait ,trait 就是接口,中有3个方法必须实现, reg isterobserver 方法和 removeobserver方法给用户使用。当有一个公告板,无论是谁,可以发出一个注册或移除的指令。如果是网络,可以加入打卡,但是移除需要使用远程代理模式。注册移除是接入者发出的,一旦天气有变化,就通知所有的用户,以上就是设计方法。

观察者设计模式会以集合的方式来管理用户,WeatherData中会出现一个集合,有集合后,包括注册、移除、通知,这样增加观察者,就可以理解成增加一个新的公告版,而不需要去修改核心类了,有一个,就动态的加入,WeatherData不会再做任何修改,以上是整个分析流程。

如果没有三个名称,一定不是规范的观察者模式:

image.png

三、代码

1.代码

代码如下:

package com.atguigu.chapter17.observer.observepattern

//这个是subject是一个trait(接口)

trait subject {

//注册

def registerobserver(o: observer)

//remove

def remcveobserver(o: observer)

//通知

def notifyobservers()

}

先创建一个subject,声明registerobserver,removeobserver,notifyobserver,observer只需要写一个接口,现在使用观察者模式,新建一个包叫observerparterner,先写出第一个trait, 直接叫接口也是可以的,其中有3个核心的方法

注册:

def registerobserver(o: observer)

remove:

def removeobserver(o: observer)

通知:

def notifyObservers()

再新建一个observer,也要声明一个核心方法,这是一个抽象方法,等待第三方及其他观察者实现方法:

package com.atguigu.chapter17.observer.observepattern

trait observer {

def update(mTemperatrue:Float,mPressure: Float,mHumidity:Float

}

先写一个CurrentConditions,要继承observer,其中的方法就是update(),写上override ,以下是气象局的公告板:

Package com.atguigu.chapter17.observer.observepattern

class currentconditions extends observer {

private var mTemperature: Float = _

private var mPressure : Float = _

private var mHumidity : Float = _def display() = {

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

println("***气象局的天气公告板Today mPressure: " + mPressure +

***")

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

***")

}

override def update(mTemperature: Float,mPressure: Float,mHumidity: Float)

//更新天气公告板

this.mTemperature = mTemperature

this.mPressure = mPressure

this.mHumidity = mHumidity//显示

display()

}

气象局是subject,等待别人来进行注册。新建一个类去继承subject,其中有核心的3个方法,必须予以实现:

package com.atguigu.chapter17.observer.observepattern

class weatherDatast extends subject{

//集合,用于管理所有的观察者

override def registerobserver(o: observer): unit = {

}

override def removeobserver(o: observer) : unit = {

}

override def notifyobservers() : unit = i

}

}

其中有一个集合用于管理所有的观察者:

Private val mobservers: listeuffel[observer] =ListBuffer()

def getTemperature( )={

mremperature}

def getpressure( )= {

mPressure}

def getHumidity( ) = {

mHumidity}

def datachange( )={

notifyObservers();}

def setData(mTemperature: Float,mPressure: Float,mHumidity: Float) ={this,mTemperature m mTemperature

this.mPressure = mPressure

this.mHumidity = mlumiditydatachange()

}

这里用的是listbuffer,下面这些方法保留不变,注册要变,如果有一个observer,调用的注册,就直接将加入到集合之中进行管理,这样就可以做到动态,加入就可以使用append;如果要移除,首先可以判断有没有东西,如果有,就把它移除,但不使用remove。

例如某个第三方不想接入,就通知所有的观察者,先把oberserver取出来就通知。天气变化的时候,气象局本身会调一次,一旦天气变化,就通知所有观察者,此处使用遍历。所以信息可以直接填入温度,湿度,压力:

//注册

override def registerobserver(o: observer): unit = {

//加入到mobservers

mobservers.append(o)

}

//移除,比如某个第三方不想接入

override def removeobserver(o: observer): unit = {

if (mobservers.contains(o)) {

mobservers -= o

}

}

//通知,天气情况变化了,我们就通知所有的观察者override def notifyobservers(): unit = {for(observer <- mobservers) {

obsecver.update(mTemoerature,mPressure,mHumidity)

}

}

}

2.测试

先创建一个气象局自己的天气公告版,此时构造器没有直接放一个observer,相当于没有传输进去,之后注册调用weatherdatast完成注册任务,一旦有数据变化,就调用即可。代码如下:

object Internetweather {

def main(args: Array[string]): unit ={

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

val mCurrentConditions = new CurrentConditions()

val mweatherDatast =new WeatherDatast

//mcurrentconditions注册

mweatherDatast .registerobserver(mCurrentConditions)

//比如天气储况变化,这星设置最新数据

mweatherDatast . setData(30, 150, 40)

}

}

四、扩展

假如有新浪的天气公告版,只需要去继承,源代码无需做任何的变化。

package com.atguigu.chapter17.observer.observepattern

class sinacurrentconditions extends observer {

private var mTemperature: Float = _

private var mPressure: Float = _

private var mHumidity: Float = _

def display() = {

println("***新浪的天气公告板Today mTemperature: " + mTemperature。"***")

println("***新浪的天气公告板Today mPressure: " + mPressure +

***")

println("***新浪局的天气公告板Today mHumidity: " + mHumidity +

***")

}

override def update(mTemperature:Float,mPressure: Float,mHumidity:Float) = {

//更新天气公告板

this.mTemperature = mTemperature

this.mPressure = mPressure

this , mtHumidity = mHumidity//显示

display())

}

}

使用时,创建新浪的天气公告版,代码如下:

val sinacurrentConditlons =new sinacurrentConditions

mweatherDatast.registerobserver(sinacurrentconditions)

如果用网络,发消息过去就行了。使用以上方法可以加入自己的业务逻辑:

def display() = {

if (this.mTemperature >40) {

println("***新浪的天气公告板Today mTemperature: " + mTemperatur+“***赶紧离开地球")

} else if (mTemperature > 16 && mTemperature < 28) {

println("***新浪的天气公告板Today mTemperature: " + mTemperatur"“***赶紧回到地球")

}

放在网络中思考,如果新浪持有weatherdataSt的引用,只需要发送消息,在消息接收的地方,动态的完成regist,不需要重启,核心(服务器)没有做任何改变,功能就增加了。

相关文章
|
机器学习/深度学习 TensorFlow 算法框架/工具
使用Python实现深度学习模型:图像风格迁移与生成
【7月更文挑战第13天】 使用Python实现深度学习模型:图像风格迁移与生成
240 2
|
网络安全 开发工具 git
Git clone仓库报错 OpenSSL SSL_read: Connection was reset
使用 Git clone 一仓库,报错,这种情况一般是网络不稳定导致,如果重新 clone 尝试是否成功;如果还出现这个问题,也有可能 ssl 证书验证方面的问题, 设置 httpsslVerify 属性取消验证,执行如下命令。
606 0
Git clone仓库报错 OpenSSL SSL_read: Connection was reset
|
Java C语言 C++
C/C++中连接函数strcat的应用(简单讲解)
C/C++中连接函数strcat的应用(简单讲解)
221 0
C/C++中连接函数strcat的应用(简单讲解)
|
机器学习/深度学习 存储 算法
sklearn:sklearn.preprocessing.StandardScaler函数的fit_transform、transform、inverse_transform简介、使用方法之详细攻略
sklearn:sklearn.preprocessing.StandardScaler函数的fit_transform、transform、inverse_transform简介、使用方法之详细攻略
|
5天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
4天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
4天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
1021 0
|
7天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
647 2