观察者模式之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 : 定义被观察者和观察者接口
package observe // 被观察者接口
type Subject interface {
Notify() // 当被观察者状态变更时,通知所有已注册的观察者,调用其自身的变更方法
State() int // 查看被观察者此时的状态
SetState(int) // 变更被观察者的状态
AddObserve(ob Observer) // 注册观察者
RemoveObserve(ob Observer) // 删除观察者
} // 观察者接口
type Observer interface {
Update(int) // 每个观察者要实现的变更自身的方法
}
2. subject_a.go : 一个被观察者实例,实现被观察者接口
package observe // 一个被观察者对象
type SubjectA struct {
state int // 观察者监听的状态数据
observers []Observer // 存储已注册的观察者对象的容器
} // 实现查看当前被观察者对象的状态
func (sa *SubjectA) State() int {
return sa.state
} // 实现更改被观察者对象的状态
func (sa *SubjectA) SetState(state int) {
sa.state = state
} // 注册观察者
func (sa *SubjectA) AddObserve(ob Observer) {
sa.observers = append(sa.observers, ob)
} // 删除观察者
func (sa *SubjectA) RemoveObserve(ob Observer) {
for i, sao := range sa.observers {
if sao == ob {
sa.observers = append(sa.observers[:i], sa.observers[i+:]...)
}
}
} // 通知所有已注册的观察者,变更自身的状态
func (sa *SubjectA) Notify() {
for _, sao := range sa.observers {
sao.Update(sa.state)
}
} // 创建被观察者对象
func NewSubjectA(state int) *SubjectA {
return &SubjectA{state: state, observers: []Observer{}}
}
3. observe_a.go: 一个观察者实例,实现观察者接口
package observe // 一个观察者对象
type ObserveA struct {
selfStatus int
} // 更新自身状态
func (oa *ObserveA) Update(state int) {
oa.selfStatus = state
} // 创建观察者对象实例
func NewObserveA(state int) *ObserveA {
return &ObserveA{selfStatus: state}
}
4. observe_b.go: 另一个观察者实例,实现观察者接口
package observe // 一个观察者对象
type ObserveB struct {
selfStatus int
} // 更新自身状态
func (oa *ObserveB) Update(state int) {
oa.selfStatus = state
} // 创建观察者对象实例
func NewObserveB(state int) *ObserveB {
return &ObserveB{selfStatus: state}
}
5. observe_test.go: 测试文件
package observe import (
"fmt"
"testing"
) func TestObserve(t *testing.T) {
sa := NewSubjectA()
oa := NewObserveA()
ob := NewObserveB() fmt.Println(sa.State())
fmt.Println(oa.selfStatus)
fmt.Println(ob.selfStatus) fmt.Println("modify state")
sa.SetState()
fmt.Println(sa.State()) fmt.Println("Add ob")
sa.AddObserve(oa)
sa.AddObserve(ob) sa.Notify()
fmt.Println("notify")
fmt.Println(sa.State())
fmt.Println(oa.selfStatus)
fmt.Println(ob.selfStatus)
}
测试结果:
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
观察者模式之Golang实现的更多相关文章
- GoLang设计模式13 - 观察者模式
观察者模式是一种行为型设计模式.这种模式允许一个实例(可以称为目标对象)发布各种事件(event)给其他实例(观察者).这些观察者会对目标对象进行订阅,这样每当目标对象发生变化时,观察者就会收到事件( ...
- Go语言实现-观察者模式
前前言 这个类经过我的正式投入使用啊,发现不对劲,这样做可能会导致线程死锁 比如你dispatch一个event,然后在这个回调里把那个事件的侦听给remove掉了,那么就会导致线程死锁(这个问题找了 ...
- Golang, 以17个简短代码片段,切底弄懂 channel 基础
(原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...
- 说说Golang的使用心得
13年上半年接触了Golang,对Golang十分喜爱.现在是2015年,离春节还有几天,从开始学习到现在的一年半时间里,前前后后也用Golang写了些代码,其中包括业余时间的,也有产品项目中的.一直 ...
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- 23种设计模式--观察者模式-Observer Pattern
一.观察者模式的介绍 观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...
- Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩
目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...
- 谈谈JS的观察者模式(自定义事件)
呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...
- golang struct扩展函数参数命名警告
今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...
随机推荐
- UVA 11748 - Rigging Elections(dfs)
UVA 11748 - Rigging Elections option=com_onlinejudge&Itemid=8&page=show_problem&category ...
- 【OI】同余方程
一.同余方程的判定 我们知道同余方程是形如 ax ≡ b (mod n) 的东西,用文字表达就是: ax和b除以n的余数相同 那么,经过如下推理:(用=代替恒等于) ax=b (mod n) ax ...
- java 多线程——并发编程模型 学习笔记
并发编程模型 ...
- android 6.1解锁
1.adb reboot bootloader 2.fastboot flashing unlock 3.power 键即可
- bzoj4082
贪心+倍增 首先如果这个问题在序列上,好像可以按右端点排序,然后从起点开始向能到的最远的地方走. 但是环上不可以,因为随即一个起点可能不是最小的. 然后神思路来了:我们先将环展开倍增,再将区间按右端点 ...
- MSP430:定时器学习TimerA
4. 定时器TA 一.时钟源1.时钟源:ACLK/SMCLK 外部TACLK/INCLK2.分频:1/2/4/8 当 (注:TACLR 置位时,分频器复位) 二.计数模式通过设置MCx可以设置定时器的 ...
- [jzoj NOIP2018模拟10.23]
丢分主要是下面几个方面: 1.T2代码交错了,有个特判没写丢了10分 2.T1线段树加等差数列写错了(其实二维差分就可以,但我当时不会) 3.T3思考再三还是为了10分写上了主席树,还是写错了 总体评 ...
- $CF1141C Polycarp Restores Permutation$
\(problem\) 这题的大致意思就是已知数值差值 求1-n的排列 如果能构成排列 则输出这个排列.如果不能则输出-1 排列的值都是 大于1 而小于n的 而且没有相同的数字. 这题最关键的是 怎么 ...
- dubbo+zookeeper下生产者和消费者配置(基于springboot开发)
一.总共分为三个目录: dubbo-api 服务的接口用于对接客户端和服务端 dubbo-client 客户端配置文件为:consumer.xml dubbo-service 服务 ...
- 题解报告:hdu 1213 How Many Tables
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1213 Problem Description Today is Ignatius' birthday. ...