观察者模式之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 ...
随机推荐
- 适合国内网速的CDH5安装
0.集群规划 说明:因为CDH能够方便的动态加入删除主机,动态改变主机上的服务,所以后面再对各机器上跑得服务进行分配. 共三台机器 操作系统: centos6.5 机器名:work01.work02. ...
- leetcode 217 Contains Duplicate 数组中是否有反复的数字
Contains Duplicate Total Accepted: 26477 Total Submissions: 73478 My Submissions Given an array o ...
- Mysql 存储引擎中InnoDB与MyISAM差别(网络整理)
1. 事务处理 innodb 支持事务功能,myisam 不支持. Myisam 的运行速度更快,性能更好. 2,select ,update ,insert ,delete 操作 MyISAM:假设 ...
- 删除svn
去掉文件下所有的.svn - CSDN博客 https://blog.csdn.net/arui_email/article/details/9055645 FOR /r D:\testsvn\p ...
- XHR ajax
谷歌搜索xhr site:cnblogs.com https://www.cnblogs.com/xiaohuochai/p/6036475.html 在Chrome的network监视中,类型为XH ...
- AJAX-responseXML 属性
如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,需要使用 responseXML 属性 cd_catalog.xml: <CATALOG><CD><T ...
- oracle基础学习---------1
1.SQL执行时间的开关 set timing on --->开 set timing off--->关 2.创建数据表.以已存在的表创建(也就是复制一个表.但表内没有数据 ...
- 解决UTF-8方法归纳
1:通过spring配置过滤器解决 <!-- 配置Spring提供的字符编码过滤器 --> <filter> <filter-name>SpringCharacte ...
- 【USACO2006 Mar】滑雪缆车 skilift
[USACO2006 Mar] 滑雪缆车 skilift Time Limit 1000 msMemory Limit 131072 KBytes Description 科罗拉多州的罗恩打算为奶牛建 ...
- D3.js 力导向图(小气泡围绕中心气泡)
html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3 ...