HeadFrist 观察者模式(Kotlin版)
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为了交互对象之间的松耦合设计而努力
气象站会通过设备获取一些气候信息,每隔一段时间发送到各个需要展示的面板上,面板显示:温度,湿度,压强
Observable(被观察者)
interface Observable {
public fun addObserver(o : Observer)
public fun deleteObserver(o : Observer)
public fun notifyObserver()
public fun setChanged()
}
气象站就是一个被观察者,通知各个面板数据的更新
WeatherData 实现Observable接口
package degisn.chapter2_observer
class WeatherData : Observable {
private var observers = ArrayList<Observer>()
get() = field
private var temperature: Float = 0f //温度
get() = field
private var humidity: Float = 0f //湿度
get() = field
private var pressure: Float = 0f //气压
get() = field
private var changed: Boolean = false
/**
* 注册观察者
*/
override fun addObserver(o: Observer) {
observers.add(o)
}
/**
* 解注册
*/
override fun deleteObserver(o: Observer) {
var i: Int = observers.indexOf(o)
if (i >= 0) {
observers.remove(o)
}
}
/**
* 通知
*/
override fun notifyObserver() {
if(changed) {
for (i in 0 until observers.size step 1) {
var observer: Observer = observers.get(i)
observer.update(temperature, humidity, pressure)
}
changed = false
}
}
override fun setChanged() {
changed = true
}
private fun measurementsChanged() {
setChanged()
notifyObserver()
}
public fun setMeasurementsChanged(temp: Float, humidity: Float, pressure: Float) {
this.temperature = temp
this.humidity = humidity
this.pressure = pressure
measurementsChanged()
}
}
Observer(观察者)
interface Observer {
public fun update(temp : Float, humidity : Float, pressure : Float)
}
DisplayElement(面板显示接口)
每一个面板显示的格式不同,采用原则:多用组合,少用继承
interface DisplayElement {
public fun display()
}
各个面板需要接收到订阅的消息,由Observable来通知
实现一个面板 CurrentConditionDisplay
class CurrentConditionDisplay : Observer, DisplayElement {
var temperature : Float = 0f
var humidity : Float = 0f
var pressure : Float = 0f
var weatherData : Observable ?
constructor(weatherData: Observable){
this.weatherData = weatherData
weatherData.addObserver(this)
}
override fun update(temp: Float, humidity: Float, pressure: Float) {
this.temperature = temp
this.humidity = humidity
this.pressure = pressure
display()
}
override fun display() {
println("Current conditions: " + temperature + " F degree " + humidity + " % humidity")
}
}
构成气象站,测试
class WeatherStation {
companion object { //静态代码块
/**
* 程序的主入口
*/
@JvmStatic
fun main(args: Array<String>){
var weatherData : WeatherData = WeatherData()
var currentConditionDisplay : CurrentConditionDisplay = CurrentConditionDisplay(weatherData)
weatherData.setMeasurementsChanged(12f, 13f, 14f)
}
}
}