观察者模式的具体概念原理,参见https://baike.baidu.com/item/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/5881786?fr=aladdin,讲的很详细。
下面是Golang实现的观察者模式,有五个文件(都在src/designer/observe/目录下),分别是:
1. defs.go : 定义被观察者和观察者接口
1 package observe
2
3 // 被观察者接口
4 type Subject interface {
5 Notify() // 当被观察者状态变更时,通知所有已注册的观察者,调用其自身的变更方法
6 State() int // 查看被观察者此时的状态
7 SetState(int) // 变更被观察者的状态
8 AddObserve(ob Observer) // 注册观察者
9 RemoveObserve(ob Observer) // 删除观察者
10 }
11
12 // 观察者接口
13 type Observer interface {
14 Update(int) // 每个观察者要实现的变更自身的方法
15 }
2. subject_a.go : 一个被观察者实例,实现被观察者接口
1 package observe
2
3 // 一个被观察者对象
4 type SubjectA struct {
5 state int // 观察者监听的状态数据
6 observers []Observer // 存储已注册的观察者对象的容器
7 }
8
9 // 实现查看当前被观察者对象的状态
10 func (sa *SubjectA) State() int {
11 return sa.state
12 }
13
14 // 实现更改被观察者对象的状态
15 func (sa *SubjectA) SetState(state int) {
16 sa.state = state
17 }
18
19 // 注册观察者
20 func (sa *SubjectA) AddObserve(ob Observer) {
21 sa.observers = append(sa.observers, ob)
22 }
23
24 // 删除观察者
25 func (sa *SubjectA) RemoveObserve(ob Observer) {
26 for i, sao := range sa.observers {
27 if sao == ob {
28 sa.observers = append(sa.observers[:i], sa.observers[i+1:]...)
29 }
30 }
31 }
32
33 // 通知所有已注册的观察者,变更自身的状态
34 func (sa *SubjectA) Notify() {
35 for _, sao := range sa.observers {
36 sao.Update(sa.state)
37 }
38 }
39
40 // 创建被观察者对象
41 func NewSubjectA(state int) *SubjectA {
42 return &SubjectA{state: state, observers: []Observer{}}
43 }
3. observe_a.go: 一个观察者实例,实现观察者接口
1 package observe
2
3 // 一个观察者对象
4 type ObserveA struct {
5 selfStatus int
6 }
7
8 // 更新自身状态
9 func (oa *ObserveA) Update(state int) {
10 oa.selfStatus = state
11 }
12
13 // 创建观察者对象实例
14 func NewObserveA(state int) *ObserveA {
15 return &ObserveA{selfStatus: state}
16 }
4. observe_b.go: 另一个观察者实例,实现观察者接口
1 package observe
2
3 // 一个观察者对象
4 type ObserveB struct {
5 selfStatus int
6 }
7
8 // 更新自身状态
9 func (oa *ObserveB) Update(state int) {
10 oa.selfStatus = state
11 }
12
13 // 创建观察者对象实例
14 func NewObserveB(state int) *ObserveB {
15 return &ObserveB{selfStatus: state}
16 }
5. observe_test.go: 测试文件
1 package observe
2
3 import (
4 "fmt"
5 "testing"
6 )
7
8 func TestObserve(t *testing.T) {
9 sa := NewSubjectA(2)
10 oa := NewObserveA(3)
11 ob := NewObserveB(4)
12
13 fmt.Println(sa.State())
14 fmt.Println(oa.selfStatus)
15 fmt.Println(ob.selfStatus)
16
17 fmt.Println("modify state")
18 sa.SetState(5)
19 fmt.Println(sa.State())
20
21 fmt.Println("Add ob")
22 sa.AddObserve(oa)
23 sa.AddObserve(ob)
24
25 sa.Notify()
26 fmt.Println("notify")
27 fmt.Println(sa.State())
28 fmt.Println(oa.selfStatus)
29 fmt.Println(ob.selfStatus)
30 }
测试结果:
jerry@jerry-TravelMate-P243:~/golearn/src/designer/observe$ go test -v === RUN TestObserve 2 3 4 modify state 5 Add ob notify 5 5 5 --- PASS: TestObserve (0.00s) PASS ok designer/observe 0.002s