Go 观察者模式

73 阅读2分钟

观察者模式是一种行为型设计模式,它能够实现对象之间的松耦合关系。在此模式中,一个对象(Subject)维护了一个观察者列表,并在它的状态改变时通知所有观察者。观察者(Observer)是依赖于Subject的对象,它将自己注册到Subject的观察者列表中,以便能够接收到Subject的通知。这种通知是通过调用观察者的回调(Callback)函数来实现的。

在Go语言中,可以使用如下方式来实现观察者模式。

Subject

Subject是被观察的对象,它维护了一个观察者列表和一个状态:

type Subject struct {
    observers []Observer
    state     int
}

Subject首先需要提供添加观察者和通知观察者的方法:

func (s *Subject) AddObserver(observer Observer) {
    s.observers = append(s.observers, observer)
}

func (s *Subject) NotifyObservers() {
    for _, observer := range s.observers {
        observer.Update(s.state)
    }
}

Observer

Observer是观察者对象,它需要提供一个Update方法,用于接收Subject的通知:

type Observer interface {
    Update(newState int)
}

ConcreteObserver

ConcreteObserver是具体的观察者对象,它实现了Observer接口:

type ConcreteObserver struct {
    name string
}

func (o *ConcreteObserver) Update(newState int) {
    fmt.Printf("Observer %s received the new state: %d\n", o.name, newState)
}

客户端代码

客户端代码需要创建一个Subject和多个ConcreteObserver,然后将ConcreteObserver注册到Subject的观察者列表中。当Subject的状态改变时,客户端代码调用Subject的NotifyObservers方法来通知所有的观察者。

func main() {
    subject := Subject{}

    observer1 := &ConcreteObserver{"Observer 1"}
    observer2 := &ConcreteObserver{"Observer 2"}

    subject.AddObserver(observer1)
    subject.AddObserver(observer2)

    subject.state = 1
    subject.NotifyObservers()
}

输出:

Observer Observer 1 received the new state: 1
Observer Observer 2 received the new state: 1

总结

在Go语言中,观察者模式可以通过使用接口来定义观察者和Subject。Subject需要提供添加观察者和通知观察者的方法,而观察者需要实现Update方法来接收Subject的通知。客户端代码需要创建Subject和具体的观察者对象,并将观察者对象注册到Subject的观察者列表中。当Subject的状态改变时,客户端代码调用Subject的NotifyObservers方法来通知所有的观察者。

完整代码

package main

import "fmt"

type Subject struct {
   observers []Observer
   state     int
}

func (s *Subject) AddObserver(observer Observer) {
   s.observers = append(s.observers, observer)
}

func (s *Subject) NotifyObservers() {
   for _, observer := range s.observers {
      observer.Update(s.state)
   }
}

type Observer interface {
   Update(newState int)
}

type ConcreteObserver struct {
   name string
}

func (o *ConcreteObserver) Update(newState int) {
   fmt.Printf("Observer %s received the new state: %d\n", o.name, newState)
}

func main() {
   subject := Subject{}

   observer1 := &ConcreteObserver{"Observer 1"}
   observer2 := &ConcreteObserver{"Observer 2"}

   subject.AddObserver(observer1)
   subject.AddObserver(observer2)

   subject.state = 1
   subject.NotifyObservers()
}