observer.go

package observer

import (
	"fmt"
)

type Observer interface {
	Notify(string)
}

type Publisher struct {
	ObserversList []Observer
}

func (s *Publisher) AddObserver(o Observer) {
	s.ObserversList = append(s.ObserversList, o)
}

func (s *Publisher) RemoveObserver(o Observer) {
	var indexToRemove int
	for i, observer := range s.ObserversList {
		if observer == o {
			indexToRemove = i
			break
		}
	}
	s.ObserversList = append(s.ObserversList[:indexToRemove], s.ObserversList[indexToRemove+1:]...)
}

func (s *Publisher) NotifyObservers(m string) {
	fmt.Printf("Publisher received message '%s' to notify observers\n", m)
	for _, observer := range s.ObserversList {
		observer.Notify(m)
	}
}

  

observer_test.go

package observer

import (
	"fmt"
	"testing"
)

type TestObserver struct {
	ID      int
	Message string
}

func (p *TestObserver) Notify(m string) {
	fmt.Printf("Observer %d: message '%s' received \n", p.ID, m)
	p.Message = m
}

func TestSubject(t *testing.T) {
	testObserver1 := &TestObserver{1, ""}
	testObserver2 := &TestObserver{2, ""}
	testObserver3 := &TestObserver{3, ""}

	publisher := Publisher{}

	t.Run("AddObserver", func(t *testing.T) {
		publisher.AddObserver(testObserver1)
		publisher.AddObserver(testObserver2)
		publisher.AddObserver(testObserver3)

		if len(publisher.ObserversList) != 3 {
			t.Fail()
		}
	})

	t.Run("RemoveObserver", func(t *testing.T) {
		publisher.RemoveObserver(testObserver2)

		fmt.Println(publisher.ObserversList)

		if len(publisher.ObserversList) != 2 {
			t.Error("The size of the observer list is not 2.")
		}

		for _, observer := range publisher.ObserversList {
			testObserver, ok := observer.(*TestObserver)
			if !ok {
				t.Fail()
			}
			if testObserver.ID == 2 {
				t.Fail()
			}
		}
	})

	t.Run("Notify", func(t *testing.T) {
		for _, observer := range publisher.ObserversList {
			printObserver, ok := observer.(*TestObserver)
			if !ok {
				t.Fail()
				break
			}
			if printObserver.Message != "" {
				t.Error("The observer's Message field weren't empty.")
			}
		}

		message := "Hello World"
		publisher.NotifyObservers(message)

		for _, observer := range publisher.ObserversList {
			printObserver, ok := observer.(*TestObserver)
			if !ok {
				t.Fail()
				break
			}
			if printObserver.Message != message {
				t.Errorf("Expected message on observer %d was "+
					"not expected: '%s' != '%s'\n", printObserver.ID,
					printObserver.Message, message)
			}
		}
	})
}

  

go语言设计模式之observer的更多相关文章

  1. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  2. Go语言设计模式之函数式选项模式

    Go语言设计模式之函数式选项模式 本文主要介绍了Go语言中函数式选项模式及该设计模式在实际编程中的应用. 为什么需要函数式选项模式? 最近看go-micro/options.go源码的时候,发现了一段 ...

  3. Go语言设计模式汇总

    目录 设计模式背景和起源 设计模式是什么 Go语言模式分类 个人观点 Go语言从面世就受到了业界的普遍关注,随着区块链的火热Go语言的地位也急速蹿升,为了让读者对设计模式在Go语言中有一个初步的了解和 ...

  4. C语言设计模式

    一 .C语言和设计模式(继承.封装.多态) C++有三个最重要的特点,即继承.封装.多态.我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性. ( ...

  5. [置顶] head first 设计模式之----Observer pattern

    浅谈设计模式之----观察者模式      观察者模式也是我们日常程序编写中碰到比较多的一种设计模式.首先,所谓观察者模式定义就是指:在对象之间定义了一对多的依赖,这样一来,当一个对象的状态发生变化的 ...

  6. 设计模式之“Observer”注疏#01

    原文首发于我的微信公众号:GeekArtT. Observer设计模式是为了解决"信息同步更新"的问题而存在的.它试图解决这样一个问题:如果有"一堆对象"都跟随 ...

  7. 面向对象设计模式——观察者(OBSERVER)模式

    定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.  Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ...

  8. C语言设计模式-封装-继承-多态

    快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...

  9. 设计模式--观察者模式Observer(对象行为型)

    一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. ...

随机推荐

  1. 解密国内BAT等大厂前端技术体系-腾讯篇(长文建议收藏)

    1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第三篇,前两篇已经讲述了阿里和百度在前端技术这几年的技术发展.这一篇从腾讯 ...

  2. LeetCode 二叉树的锯齿形层次遍历

    第103题 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 例如: 给定二叉树 [3,9,20,null,null,15,7] ...

  3. Oracle模糊查询CONCAT参数个数无效

    在使用MyBatis操作Oracle数据库的时候,写模糊查询突然发现原本在MySql中正确的代码,在Oracle中报错,参数个数无效 <if test="empId!=null and ...

  4. shiro认证授权

    一.shiro基础概念 Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份: Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户 ...

  5. 学习DDD的初步尝试,从最基础的开始,业务介绍,划分限界上下文 ,建立模型

    Conference业务简介 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的用户有两类: 1:客户,可以创建和管理会议. 2:会议座位预定者,可以预订会 ...

  6. 深入解析ReentrantReadWriteLock

    前言: 在Java的锁中很多锁都是同一时刻只允许一个线程访问,今天就来看看一个特殊的锁——读写锁.它的特殊之处就在于同一时刻可以运行多个读线程访问或者有一个写线程在访问.能够大大的提高并发性和吞吐量 ...

  7. Centos8尝鲜

    Centos 8阿里云下载地址https://mirrors.aliyun.com/centos/8.0.1905/isos/x86_64/ Centos8的一些变化 网络服务: 在/etc/sysc ...

  8. Redis学习(一)简介

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...

  9. Python爬虫基础——HTML、CSS、JavaScript、JQuery网页前端技术

    一.HTML HTML是Hyper Text Markup Language(超文本标记语言)的缩写. HTML不是一种编程语言,而是标记语言. HTML的语法 双标签: 单标签: HTML的元素和属 ...

  10. 阿里面试官:字符串在JVM中如何存放?90%的人就真的只回答在哪里存放

    目录: 一道面试题的引出 案例分析 intern 源码分析 总结 1. 一道面试题的引出 在面试BAT这种一线大厂时,如果面试官问道:字符串在 JVM 中如何存放?大多数人能顺利的给出如下答案: 字符 ...