观察者模式原理

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,会自动通知所有观察者对象进行相应的更新。
 
观察者模式的核心思想是将主题和观察者对象解耦,使它们可以独立地进行变化。主题对象负责维护一组观察者对象,并在自身状态发生变化时通知观察者对象。观察者对象则定义了在接收到主题通知时所需要执行的操作。
 
在观察者模式中,主题对象通常会提供注册和取消注册观察者对象的方法,以及通知观察者对象的方法。观察者对象则需要实现一个更新方法,用于接收主题对象的通知并进行相应的处理。
 
当主题对象的状态发生变化时,它会遍历已注册的观察者对象列表,并依次调用它们的更新方法。这样,所有观察者对象都能及时获取到主题对象的最新状态,并进行相应的处理。
 
观察者模式的优点包括了解耦主题和观察者对象、支持动态注册和取消注册观察者对象、易于扩展等。它适用于当一个对象的改变需要同时通知其他多个对象时,或者当一个对象需要通知其他对象,但又希望尽量减少与其他对象的耦合性的场景。
 
总结一下,观察者模式通过定义一对多的依赖关系,实现了主题对象和观察者对象的解耦。主题对象在状态发生变化时会自动通知观察者对象,使其能够及时作出相应的处理。这种模式能够提高系统的灵活性和可扩展性,适用于多个对象之间存在依赖关系的场景。

下面是一个使用Go语言实现观察者模式的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package main
 import (
	"fmt"
)
 // 定义观察者接口
type Observer interface {
	Update(message string)
}
 // 定义主题接口
type Subject interface {
	Register(observer Observer)
	Unregister(observer Observer)
	Notify(message string)
}
 // 具体观察者
type ConcreteObserver struct {
	name string
}
 func (o *ConcreteObserver) Update(message string) {
	fmt.Printf("%s 收到通知:%s\n", o.name, message)
}
 // 具体主题
type ConcreteSubject struct {
	observers []Observer
}
 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(message string) {
	for _, observer := range s.observers {
		observer.Update(message)
	}
}
 func main() {
	subject := &ConcreteSubject{}
 	observer1 := &ConcreteObserver{name: "观察者1"}
	observer2 := &ConcreteObserver{name: "观察者2"}
	observer3 := &ConcreteObserver{name: "观察者3"}
 	subject.Register(observer1)
	subject.Register(observer2)
	subject.Register(observer3)
 	subject.Notify("主题发生变化了!")
 	subject.Unregister(observer2)
 	subject.Notify("主题再次发生变化了!")
}

在上面的示例中,我们定义了 Observer 接口和 Subject 接口,分别表示观察者和主题。然后,我们实现了具体的观察者 ConcreteObserver 和具体的主题 ConcreteSubject 。观察者实现了 Update 方法来接收主题的通知,主题实现了 Register 、 Unregister 和 Notify 方法来注册观察者、取消注册观察者和通知观察者。

在 main 函数中,我们创建了一个具体的主题对象 subject ,并创建了三个具体的观察者对象 observer1 、 observer2 和 observer3 。然后,我们通过 Register 方法将观察者注册到主题中,并通过 Notify 方法通知观察者主题发生了变化。接着,我们通过 Unregister 方法取消注册了 observer2 ,再次通过 Notify 方法通知观察者主题再次发生了变化。

当我们运行上述代码时,输出结果如下: