观察者模式:
对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject 通知 Observer 变化,比如这里的奶站是 Subject,是 1 的一方。用户时 Observer, 是 n 的一方。
观察者模式类似订牛奶业务
- 奶站/气象局:Subject
- 用户/第三方网站:Observer
Subject
:登记注册、移除和通知
- registerObserver 注册
- removeObserver 移除
- notifyObservers() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取, 也可能是实施推送,看具体需求定
Observer
:接收输入
自己实现观察者模式代码示例:
Observer 抽象类
trait Observer {
//抽象方法,等待其它的观察者实现
def update(mTemperatrue: Float, mPressure: Float, mHumidity: Float)
}
subject抽象类
//这个是Subject 是一个trait(接口)
trait Subject {
//注册
def registerObserver(o: ObServer)
//remove
def removeObserver(o: ObServer)
//通知
def notifyObservers()
}
观察者实现类1
class SinaCurrentConditions extends Observer {
private var mTemperature: Float = _
private var mPressure: Float = _
private var mHumidity: Float = _
def display() = {
if (this.mTemperature > 40) {
println("***新浪的天气公告板 Today mTemperature: " + mTemperature + "*** 赶紧离开地球")
} else if (mTemperature > 16 && mTemperature < 28) {
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()
}
}
观察者实现类2
//气象局的公告板
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实现类: 实现订阅, 取消订阅, 推送, 通知等功能
从中我们可以看出, 可以动态引入, 删除观察者, 在调用观察者的observer.update()
时, 有点抽象工厂
的影子
class WeatherDataSt extends Subject {
private var mTemperature: Float = _
private var mPressure: Float = _
private var mHumidity: Float = _
//集合,用于管理所有的观察者
private val mObservers: ListBuffer[ObServer] = ListBuffer()
def getTemperature() = {
mTemperature
}
def getPressure() = {
mPressure
}
def getHumidity() = {
mHumidity
}
def dataChange() = {
//一旦天气变化,就通知所有观察者
notifyObservers()
}
//天气变化
def setData(mTemperature: Float, mPressure: Float, mHumidity: Float) = {
this.mTemperature = mTemperature
this.mPressure = mPressure
this.mHumidity = mHumidity
dataChange()
}
//注册
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) {
observer.update(mTemperature, mPressure, mHumidity)
}
}
}
main
object InternetWeather {
def main(args: Array[String]): Unit = {
//创建个月气象局的天气公告板
val mCurrentConditions = new CurrentConditions()
val mWeatherDataSt = new WeatherDataSt
//mCurrentConditions 注册
mWeatherDataSt.registerObserver(mCurrentConditions)
//创建一个新浪的天气公告板
val sinaCurrentConditions = new SinaCurrentConditions
mWeatherDataSt.registerObserver(sinaCurrentConditions)
//比如天气情况变化,这里设置最新数据
mWeatherDataSt.setData(20, 150, 40)
}
}
JDK内置了观察者模式的实现方案:
java.util.Observable
类比本文Subject
java.util.Observer
类比本文Observer