观察者模式的具体概念原理,参见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. The Pragmatic Programmer 读书笔记之中的一个 DRY-Don’t Repeat Youself

     The Pragmatic Programmer读书笔记之中的一个 DRY-Don't Repeat Youself 尽管自己买了非常多软件project方面的书,可是由于时间的问题.一直没有静 ...

  2. Codeforces--633D--Fibonacci-ish (map+去重)(twice)

     Fibonacci-ish Time Limit: 3000MS   Memory Limit: 524288KB   64bit IO Format: %I64d & %I64u Su ...

  3. java事件处理机制(自定义事件)

    java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 2.event sourc ...

  4. E20170916-hm

    sassy   adj. 无礼的; 漂亮的; <非正,美> <贬>粗鲁的; <褒>时髦的; digest vt. 消化; 整理; compressor  n. 压气 ...

  5. 网站防止用户复制的js方法

    <script type="text/javascript">function stop() {return false;}document.oncontextmenu ...

  6. poj1988Cute Stacking

    题目大意:有几个stack,初始里面有一个cube.支持两种操作:1.move x y: 将x所在的stack移动到y所在stack的顶部.2.count x:数在x所在stack中,在x之下的cub ...

  7. 【翻译】- EffectiveAkka-第二章(一)

    Actor使用模式 现在我们已经了解了可以创建的actor系统的不同类型,那么我们在编写基于actor的应用程序时,可以采用什么样的使用模式,以便避免出现常见错误呢? 下面就让我们看看其中使用模式. ...

  8. BZOJ 5277 IQ题orz

    思路: 首先我们注意到,对一个序列按分割点分开以后分别冒泡其实就相当于对整个序列进行冒泡.每一个元素都会对复杂度贡献1,除非一个元素两边的分割点都出现了.因此我们可以完全忽略快排的递归过程.只需考虑每 ...

  9. ANDROID 开发之 SQLite

    SQLite简介 Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLit ...

  10. form表单中图片也可以当作提交按钮

    点击图片按钮时,不光提交其他输入框信息,还把鼠标点击图片上的x,y坐标也传输过去了