前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go:使用观察者模式

Go:使用观察者模式

作者头像
运维开发王义杰
发布2023-08-10 19:25:25
1240
发布2023-08-10 19:25:25
举报

观察者模式是一种行为设计模式,它定义了对象间的依赖关系,当一个对象状态发生改变时,其依赖对象都会收到通知并且更新。这是一种一对多的依赖关系。在这篇文章中,我们将探讨如何在Go语言中实现观察者模式,并通过一个天气预报系统实例来进行说明。

  1. 定义观察者和被观察者接口

首先,我们定义观察者和被观察者的接口。

代码语言:javascript
复制
// Observer 是观察者接口
type Observer interface {
    Update(temperature float64, humidity float64, pressure float64)
}

// Subject 是被观察者接口
type Subject interface {
    RegisterObserver(o Observer)
    RemoveObserver(o Observer)
    NotifyObservers()
}

  1. 实现具体的观察者

然后,我们实现具体的观察者,例如天气预报和实时天气状况展示。

代码语言:javascript
复制
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")
    }
}

  1. 实现具体的被观察者

接下来,我们实现具体的被观察者,也就是天气数据。

代码语言:javascript
复制
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:]...)
}

  1. 客户端代码

最后,我们的客户端代码看起来像这样:

代码语言:javascript
复制
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)
}

总结

观察者模式为我们提供了一种对象间的一对多的依赖关系,这种模式可以帮助我们建立一个自动通知和更新系统。希望本文能够帮助你理解观察者模式,并在实际开发中找到其应用场景。如果你觉得本文有价值,欢迎分享给你的朋友。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维开发王义杰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档