观察者模式的具体概念原理,参见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实现的更多相关文章

  1. GoLang设计模式13 - 观察者模式

    观察者模式是一种行为型设计模式.这种模式允许一个实例(可以称为目标对象)发布各种事件(event)给其他实例(观察者).这些观察者会对目标对象进行订阅,这样每当目标对象发生变化时,观察者就会收到事件( ...

  2. Go语言实现-观察者模式

    前前言 这个类经过我的正式投入使用啊,发现不对劲,这样做可能会导致线程死锁 比如你dispatch一个event,然后在这个回调里把那个事件的侦听给remove掉了,那么就会导致线程死锁(这个问题找了 ...

  3. Golang, 以17个简短代码片段,切底弄懂 channel 基础

    (原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...

  4. 说说Golang的使用心得

    13年上半年接触了Golang,对Golang十分喜爱.现在是2015年,离春节还有几天,从开始学习到现在的一年半时间里,前前后后也用Golang写了些代码,其中包括业余时间的,也有产品项目中的.一直 ...

  5. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  6. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  7. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  8. 谈谈JS的观察者模式(自定义事件)

    呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...

  9. golang struct扩展函数参数命名警告

    今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...

随机推荐

  1. 软件project—思考项目开发那些事(一)

    阅读文件夹: 1.背景 2.项目管理,质量.度量.进度 3.软件开发是一种设计活动而不是建筑活动 4.高速开发(简单的系统结构与复杂的业务模型) 5.技术人员的业务理解与产品经理的业务理解的终于业务模 ...

  2. node.js应用Redis初步

    node.js下使用Redis,首先: 1.有一台安装了Redis的服务器,当然,安装在本机也行 2.本机,也就是客户端,要装node.js 3.项目要安装nodejs_redis模块 注意第 3 点 ...

  3. PhoneGap:JS跨域请求

    PhoneGap开发,理论上好处多多.但因为javascript是其中的主角,并且是直接存放于手机,跟服务器数据交互,就会有一个跨域访问的问题. 当然,这个问题肯定有解决方案,不然的话,这种利用Pho ...

  4. Codeforces Round #250 (Div. 2)B. The Child and Set 暴力

    B. The Child and Set   At the children's day, the child came to Picks's house, and messed his house ...

  5. [水题]4242 果实计数&&3214 采访对象

    4242 果实计数  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 淘淘家有棵奇怪的苹果树,这棵树共有n+1层 ...

  6. WCF Odata 开放数据协议应用

    OData简介 说起 WCF Data Service ,不得不说的是 OData.对于一个标准的 Web 服务,它往往会提供了一些功能,比如说:订货.退货这些,然后使用者通过HTTP协议来使用这些功 ...

  7. CNN 文本分类模型优化经验——关键点:加卷积层和FC可以提高精度,在FC前加BN可以加快收敛,有时候可以提高精度,FC后加dropout,conv_1d的input维度加大可以提高精度,但是到256会出现OOM。

    network = tflearn.input_data(shape=[None, max_len], name='input') network = tflearn.embedding(networ ...

  8. influxdb入门——和mongodb一样可以动态增加字段

    ./influxd [--config yourconfigfile 2> /dev/null]  之所以重定向 因为默认log是stderr 再启动客户端./influx > CREAT ...

  9. shell脚本-循环选择语句

    shell脚本-循环选择语句 过程式编程语言: 顺序执行 选择执行 循环执行 注:条件中的变量,可以在执行语句中使用,不用在加上"$". if语句 根据命令的退出状态来执行命令 单 ...

  10. 如何使jquery性能最佳

    转自 http://www.cnblogs.com/mo-beifeng/archive/2012/02/02/2336228.html 1. 使用最新版本的jQuery jQuery的版本更新很快, ...