观察者模式是一种行为设计模式,它定义了对象间的依赖关系,当一个对象状态发生改变时,其依赖对象都会收到通知并且更新。这是一种一对多的依赖关系。在这篇文章中,我们将探讨如何在Go语言中实现观察者模式,并通过一个天气预报系统实例来进行说明。
首先,我们定义观察者和被观察者的接口。
// Observer 是观察者接口
type Observer interface {
Update(temperature float64, humidity float64, pressure float64)
}
// Subject 是被观察者接口
type Subject interface {
RegisterObserver(o Observer)
RemoveObserver(o Observer)
NotifyObservers()
}
然后,我们实现具体的观察者,例如天气预报和实时天气状况展示。
type CurrentConditionsDisplay struct {
temperature float64
humidity float64
pressure float64
}
func (ccd *CurrentConditionsDisplay) Update(temperature float64, humidity float64, pressure float64) {
ccd.temperature = temperature
ccd.humidity = humidity
ccd.pressure = pressure
ccd.display()
}
func (ccd *CurrentConditionsDisplay) display() {
fmt.Printf("Current conditions: %.2f F degrees, %.2f humidity and %.2f pressure\n", ccd.temperature, ccd.humidity, ccd.pressure)
}
type ForecastDisplay struct {
currentPressure float64
lastPressure float64
}
func (fd *ForecastDisplay) Update(_, _, pressure float64) {
fd.lastPressure = fd.currentPressure
fd.currentPressure = pressure
fd.display()
}
func (fd *ForecastDisplay) display() {
fmt.Printf("Forecast: ")
if fd.currentPressure > fd.lastPressure {
fmt.Println("Improving weather on the way!")
} else if fd.currentPressure == fd.lastPressure {
fmt.Println("More of the same")
} else if fd.currentPressure < fd.lastPressure {
fmt.Println("Watch out for cooler, rainy weather")
}
}
接下来,我们实现具体的被观察者,也就是天气数据。
type WeatherData struct {
observers []Observer
temperature float64
humidity float64
pressure float64
}
func NewWeatherData() *WeatherData {
return &WeatherData{
observers: make([]Observer, 0),
}
}
func (wd *WeatherData) RegisterObserver(o Observer) {
wd.observers = append(wd.observers, o)
}
func (wd *WeatherData) RemoveObserver(o Observer) {
wd.observers = removeFromSlice(wd.observers, o)
}
func (wd *WeatherData) NotifyObservers() {
for _, observer := range wd.observers {
observer.Update(wd.temperature, wd.humidity, wd.pressure)
}
}
func (wd *WeatherData) MeasurementsChanged() {
wd.NotifyObservers()
}
func (wd *WeatherData) SetMeasurements(temperature float64, humidity float64, pressure float64) {
wd.temperature = temperature
wd.humidity = humidity
wd.pressure = pressure
wd.MeasurementsChanged()
}
func removeFromSlice(observerSlice []Observer, observerToRemove Observer) []Observer {
observerIndex := -1
for i, observer := range observerSlice {
if observer == observerToRemove {
observerIndex = i
break
}
}
if observerIndex == -1 {
return observerSlice
}
return append(observerSlice[:observerIndex], observerSlice[observerIndex+1:]...)
}
最后,我们的客户端代码看起来像这样:
func main() {
weatherData := NewWeatherData()
new(CurrentConditionsDisplay).Update = weatherData.RegisterObserver
new(ForecastDisplay).Update = weatherData.RegisterObserver
weatherData.SetMeasurements(80, 65, 30.4)
weatherData.SetMeasurements(82, 70, 29.2)
weatherData.SetMeasurements(78, 90, 29.2)
}
总结
观察者模式为我们提供了一种对象间的一对多的依赖关系,这种模式可以帮助我们建立一个自动通知和更新系统。希望本文能够帮助你理解观察者模式,并在实际开发中找到其应用场景。如果你觉得本文有价值,欢迎分享给你的朋友。