观察者模式

定义

它定义了一种对象之间的一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式主要包括两类角色:主题(Subject)和观察者(Observer)。

观察者模式可以用一个现实生活中的例子来解释:杂志订阅。

假设有一家杂志出版社,负责出版一本杂志。这家出版社有很多订阅者。当每期杂志出版时,出版社需要将杂志寄给所有的订阅者。在这个过程中,出版社就是“主题”,订阅者们则是“观察者”。

主题(出版社)与观察者(订阅者)之间存在一种依赖关系。当主题有新的杂志出版时,所有依赖于它的观察者都会得到通知,并收到新的杂志。订阅者可以随时取消订阅,这时出版社会将他们从观察者名单中移除,以后新的杂志就不再寄给他们。

观察者模式就是这样一种设计模式,当一个对象(主题)的状态发生变化时,所有依赖于它的对象(观察者)都会得到通知并自动更新。这种模式使得主题和观察者之间的依赖关系松散,使得它们可以独立变化,降低了系统的耦合度。

示意图

img

​ UML diagram

Subject(主题)
   |----------------|----------------|
   |                |                |
Observer1       Observer2       Observer3

在这个示意图中,主题(Subject)是观察者们依赖的对象。当Subject的状态发生变化时,所有依赖于它的观察者(Observer1,Observer2,Observer3)都会得到通知并自动更新。

例子

package main

import "fmt"

// Subject 接口
type Subject interface {
    Register(observer Observer)
    Unregister(observer Observer)
    Notify()
}

// Observer 接口
type Observer interface {
    Update(message string)
}

// ConcreteSubject 具体主题
type ConcreteSubject struct {
    observers []Observer
    message   string
}

func (s *ConcreteSubject) Register(observer Observer) {
    s.observers = append(s.observers, observer)
}

func (s *ConcreteSubject) Unregister(observer Observer) {
    for i, obs := range s.observers {
        if obs == observer {
            s.observers = append(s.observers[:i], s.observers[i+1:]...)
            break
        }
    }
}

func (s *ConcreteSubject) Notify() {
    for _, observer := range s.observers {
        observer.Update(s.message)
    }
}

func (s *ConcreteSubject) SetMessage(message string) {
    s.message = message
    s.Notify()
}

// ConcreteObserver 具体观察者
type ConcreteObserver struct {
    id      int
    message string
}

func (o *ConcreteObserver) Update(message string) {
    o.message = message
    fmt.Printf("Observer %d received message: %s\n", o.id, o.message)
}

func main() {
    subject := &ConcreteSubject{}

    observer1 := &ConcreteObserver{id: 1}
    observer2 := &ConcreteObserver{id: 2}

    subject.Register(observer1)
    subject.Register(observer2)

    subject.SetMessage("Hello, Observer!")

    subject.Unregister(observer1)

    subject.SetMessage("Observer1 has left.")
}

在这个例子中,ConcreteSubject是具体主题,实现了Subject接口,具有注册、注销和通知观察者的方法。ConcreteObserver是具体观察者,实现了Observer接口,具有更新自身状态的方法。


zhaobuqi
1 声望1 粉丝

« 上一篇
go中间件