观察者模式是一种行为设计模式,它允许你定义一种订阅机制,让多个对象监听某一个对象的状态变化。当被监听对象的状态发生变化时,它会自动通知所有订阅了它的对象。
解耦:观察者模式使得观察者和被观察者之间保持松耦合,观察者无需知道被观察者的具体实现细节。
动态交互:可以在运行时动态地添加或删除观察者。
扩展性:易于扩展,新增观察者无需修改被观察者代码。
事件处理系统:如GUI系统中,事件源(按钮点击、窗口关闭等)和事件处理程序之间的交互。
发布/订阅系统:如新闻订阅、邮件通知等。
数据绑定:如MVC框架中的视图与模型之间的交互。
下面是一个简单的Go语言实现,模拟一个天气预报系统,气象站(被观察者)发布天气变化,多个订阅者(观察者)接收并处理这些信息。
package main
import (
"fmt"
)
// Observer 接口定义了观察者的行为
type Observer interface {
Update(temp float64, humidity float64, pressure float64)
}
// Subject 接口定义了被观察者的行为
type Subject interface {
RegisterObserver(o Observer)
RemoveObserver(o Observer)
NotifyObservers()
}
// WeatherData 结构体表示被观察者,即气象站
type WeatherData struct {
observers []Observer
temperature float64
humidity float64
pressure float64
}
// RegisterObserver 方法用于注册观察者
func (w *WeatherData) RegisterObserver(o Observer) {
w.observers = append(w.observers, o)
}
// RemoveObserver 方法用于移除观察者
func (w *WeatherData) RemoveObserver(o Observer) {
for i, observer := range w.observers {
if observer == o {
w.observers = append(w.observers[:i], w.observers[i+1:]...)
break
}
}
}
// NotifyObservers 方法用于通知所有观察者
func (w *WeatherData) NotifyObservers() {
for _, observer := range w.observers {
observer.Update(w.temperature, w.humidity, w.pressure)
}
}
// MeasurementsChanged 方法用于当测量值改变时通知观察者
func (w *WeatherData) MeasurementsChanged() {
w.NotifyObservers()
}
// SetMeasurements 方法用于设置新的测量值
func (w *WeatherData) SetMeasurements(temperature float64, humidity float64, pressure float64) {
w.temperature = temperature
w.humidity = humidity
w.pressure = pressure
w.MeasurementsChanged()
}
// CurrentConditionsDisplay 结构体表示一个观察者,即当前天气显示
type CurrentConditionsDisplay struct {
temperature float64
humidity float64
weatherData *WeatherData
}
// Update 方法实现了观察者的行为
func (c *CurrentConditionsDisplay) Update(temp float64, humidity float64, pressure float64) {
c.temperature = temp
c.humidity = humidity
c.display()
}
// display 方法用于显示当前天气信息
func (c *CurrentConditionsDisplay) display() {
fmt.Printf("Current conditions: %.1fF degrees and %.1f%% humidity\n", c.temperature, c.humidity)
}
func main() {
// 天气信息
weatherData := &WeatherData{}
// 显示天气信息 观察者行为
currentDisplay := &CurrentConditionsDisplay{weatherData: weatherData}
// 注册观察者
weatherData.RegisterObserver(currentDisplay)
// 天气数据变化
weatherData.SetMeasurements(80, 65, 30.4)
weatherData.SetMeasurements(82, 70, 29.2)
weatherData.SetMeasurements(78, 90, 29.2)
}