观察者模式(Observer)定义了对象之间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知。在Go中,可以使用接口和切片实现观察者模式:
package observer
import "fmt"
// 观察者接口
type Observer interface {
Update(subject *Subject)
}
// 主题结构体
type Subject struct {
observers []Observer
state int
}
// 注册观察者
func (s *Subject) Attach(observer Observer) {
s.observers = append(s.observers, observer)
}
// 移除观察者
func (s *Subject) Detach(observer Observer) {
for i, obs := range s.observers {
if obs == observer {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
// 通知所有观察者
func (s *Subject) Notify() {
for _, observer := range s.observers {
observer.Update(s)
}
}
// 改变状态
func (s *Subject) SetState(state int) {
s.state = state
fmt.Printf("主题状态改变为: %d\n", state)
s.Notify()
}
// 获取状态
func (s *Subject) GetState() int {
return s.state
}
// 具体观察者A
type ConcreteObserverA struct {
ID string
}
func (o ConcreteObserverA) Update(subject *Subject) {
fmt.Printf("观察者A(%s)收到更新: 状态 = %d\n", o.ID, subject.GetState())
}
// 具体观察者B
type ConcreteObserverB struct {
ID string
}
func (o ConcreteObserverB) Update(subject *Subject) {
fmt.Printf("观察者B(%s)收到更新: 状态 = %d\n", o.ID, subject.GetState())
}
// main.go
package main
import (
"myapp/observer"
)
func main() {
// 创建主题
subject := &observer.Subject{}
// 创建观察者
observerA1 := observer.ConcreteObserverA{ID: "A1"}
observerA2 := observer.ConcreteObserverA{ID: "A2"}
observerB1 := observer.ConcreteObserverB{ID: "B1"}
// 注册观察者
subject.Attach(observerA1)
subject.Attach(observerA2)
subject.Attach(observerB1)
// 改变状态,触发通知
subject.SetState(1)
// 取消注册一个观察者
subject.Detach(observerA1)
// 再次改变状态
subject.SetState(2)
}