观察者模式之Golang实现
观察者模式的具体概念原理,参见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