首页 > 其他分享 >14 观察者模式 -- go语言设计模式

14 观察者模式 -- go语言设计模式

时间:2023-08-15 21:01:02浏览次数:38  
标签:observer -- fmt listener Println Badthing func go 设计模式

观察者模式也叫做发布-订阅模式。观察者通过通知器(发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者只从通知器得到它订阅的通知。

观察者模式的实现代码

package main

import "fmt"

//--------- 抽象层 --------

//抽象的观察者
type Listener interface {
	OnTeacherComming()	 //观察者得到通知后要触发的动作
}

type Notifier interface {
	AddListener(listener Listener)
	RemoveListener(listener Listener)
	Notify()
}

//--------- 实现层 --------
//观察者学生
type StuZhang3 struct {
	Badthing string
}

func (s *StuZhang3) OnTeacherComming() {
	fmt.Println("张3 停止 ", s.Badthing)
}

func (s *StuZhang3) DoBadthing() {
	fmt.Println("张3 正在", s.Badthing)
}

type StuZhao4 struct {
	Badthing string
}

func (s *StuZhao4) OnTeacherComming() {
	fmt.Println("赵4 停止 ", s.Badthing)
}

func (s *StuZhao4) DoBadthing() {
	fmt.Println("赵4 正在", s.Badthing)
}

type StuWang5 struct {
	Badthing string
}

func (s *StuWang5) OnTeacherComming() {
	fmt.Println("王5 停止 ", s.Badthing)
}

func (s *StuWang5) DoBadthing() {
	fmt.Println("王5 正在", s.Badthing)
}


//通知者班长
type ClassMonitor struct {
	listenerList []Listener //需要通知的全部观察者集合
}

func (m *ClassMonitor) AddListener(listener Listener) {
	m.listenerList = append(m.listenerList, listener)
}

func (m *ClassMonitor) RemoveListener(listener Listener) {
	for index, l := range m.listenerList {
		//找到要删除的元素位置
		if listener == l {
			//将删除的点前后的元素链接起来
			m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)
			break
		}
	}
}

func (m* ClassMonitor) Notify() {
	for _, listener := range m.listenerList {
		//依次调用全部观察的具体动作
		listener.OnTeacherComming()
	}
}


func main() {
	s1 := &StuZhang3{
		Badthing: "抄作业",
	}
	s2 := &StuZhao4{
		Badthing: "玩王者荣耀",
	}
	s3 := &StuWang5{
		Badthing: "看赵四玩王者荣耀",
	}

	classMonitor := new(ClassMonitor)

	fmt.Println("上课了,但是老师没有来,学生们都在忙自己的事...")
	s1.DoBadthing()
	s2.DoBadthing()
	s3.DoBadthing()

	classMonitor.AddListener(s1)
	classMonitor.AddListener(s2)
	classMonitor.AddListener(s3)

	fmt.Println("这时候老师来了,班长给学什么使了一个眼神...")
	classMonitor.Notify()
}

终端输出

1.png

观察者模式的代码拆分

1.项目的准备工作

找到 go 的 GOPATH

$ go env		//可以查看 GOPATH

在 GOPATH 目录下创建3个文件夹

1.bin文件夹		-- 存放编译后的二进制文件

2.pkg文件夹		-- 存放编译后的库文件

3.src文件夹		-- 存放源码文件

2.创建文件夹

//	-- 在项目文件夹 observer_mode 里创建新文件夹

//	observer	-- 存放装饰者的全部文件

2.png

3.接口文件 -- observer文件夹

文件1 -- listener.go

package observer

//抽象的观察者
type Listener interface {
	OnTeacherComming()	 //观察者得到通知后要触发的动作
}

文件2 -- notifier.go

package observer

// 抽象通知人
type Notifier interface {
	AddListener(listener Listener)
	RemoveListener(listener Listener)
	Notify()
}

4.结构体文件 -- observer文件夹

文件1 -- stuzhang3.go

package observer

import "fmt"

//观察者学生
type StuZhang3 struct {
	Badthing string
}

func (s *StuZhang3) OnTeacherComming() {
	fmt.Println("张3 停止 ", s.Badthing)
}

func (s *StuZhang3) DoBadthing() {
	fmt.Println("张3 正在", s.Badthing)
}

文件2 -- zhao4.go

package observer

import "fmt"

//观察者学生
type StuZhao4 struct {
	Badthing string
}

func (s *StuZhao4) OnTeacherComming() {
	fmt.Println("赵4 停止 ", s.Badthing)
}

func (s *StuZhao4) DoBadthing() {
	fmt.Println("赵4 正在", s.Badthing)
}

文件3 -- stuwang5.go

package observer

import "fmt"

//观察者学生
type StuWang5 struct {
	Badthing string
}

func (s *StuWang5) OnTeacherComming() {
	fmt.Println("王5 停止 ", s.Badthing)
}

func (s *StuWang5) DoBadthing() {
	fmt.Println("王5 正在", s.Badthing)
}

文件4 -- classmonitor.go

package observer

//通知者班长
type ClassMonitor struct {
	listenerList []Listener //需要通知的全部观察者集合
}

func (m *ClassMonitor) AddListener(listener Listener) {
	m.listenerList = append(m.listenerList, listener)
}

func (m *ClassMonitor) RemoveListener(listener Listener) {
	for index, l := range m.listenerList {
		//找到要删除的元素位置
		if listener == l {
			//将删除的点前后的元素链接起来
			m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)
			break
		}
	}
}

func (m* ClassMonitor) Notify() {
	for _, listener := range m.listenerList {
		//依次调用全部观察的具体动作
		listener.OnTeacherComming()
	}
}

5.主文件 -- main.go 在项目文件夹

package main

import (
	"design/observer_mode/observer"
	"fmt"
)

func main() {
	s1 := &(observer.StuZhang3{
		Badthing: "抄作业",
	})
	s2 := &(observer.StuZhao4{
			Badthing: "玩王者荣耀",
		})
	s3 := &observer.StuWang5{
		Badthing: "看赵四玩王者荣耀",
	}

	classMonitor := new(observer.ClassMonitor)

	fmt.Println("上课了,但是老师没有来,学生们都在忙自己的事...")
	s1.DoBadthing()
	s2.DoBadthing()
	s3.DoBadthing()

	classMonitor.AddListener(s1)
	classMonitor.AddListener(s2)
	classMonitor.AddListener(s3)

	fmt.Println("这时候老师来了,班长给学什么使了一个眼神...")
	classMonitor.Notify()
}

终端输出

3.png

6.全部文件图

4.png

标签:observer,--,fmt,listener,Println,Badthing,func,go,设计模式
From: https://blog.51cto.com/u_14483476/7093633

相关文章

  • TCP
    1.如何理解UDP和TCP?区别?应用场景?一、UDPUDP(UserDatagramProtocol),用户数据包协议,是一个简单的面向数据报的通信协议,即对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层也就是说无论应用层交给UDP多长的报文,它统统发送,一次发送一个报文而......
  • 如何搭建一个演讲训练门户网站?
    搭建一个演讲训练门户网站可以帮助人们提升演讲能力和表达能力,提供相关的教学资源和训练工具。本文将介绍搭建演讲训练门户网站的步骤和要点。首先,确定网站的目标和定位。演讲训练门户网站的目标是提供演讲训练相关的教学资源和工具,帮助用户提升演讲能力和表达能力。定位可以根据......
  • c# 利用数据库将程序加密隐藏?
    下面将介绍如何通过LiteDB将自己的程序进行加密,首先介绍一下LiteDB。LiteDBLiteDB是一个轻量级的嵌入式数据库,它是用C#编写的,适用于.NET平台。它的设计目标是提供一个简单易用的数据库解决方案,可以在各种应用程序中使用。LiteDB使用单个文件作为数据库存储,这个文件可以在磁盘......
  • 视觉创作新境界——VideoBlog Ai服务介绍
    在数字化时代,多媒体内容已成为传播和吸引注意力的重要手段。为了满足这一需求,VideoBlogAi应运而生,它能够将博客链接转化为引人注目的AI视频,让内容更加生动有趣。VideoBlogAi不仅是一款工具,更是一种创意的媒介,本文将深入介绍VideoBlogAi服务的作用及其在内容创作领域的巨大影响。......
  • 网页设计与网站建设连接数据库
    网页设计与网站建设连接数据库是实现动态网站的重要环节。通过连接数据库,网站可以实现用户数据的存储和读取、动态内容的生成和更新、用户交互的实现等功能。本文将介绍网页设计与网站建设连接数据库的基本步骤和要点。首先,选择合适的数据库管理系统。常见的数据库管理系统包括MyS......
  • 这是一个空白文档
    添加依赖:spring-boot-starter-data-redis和spring-boot-starter-cache在具体Redis应用中有2种方式:编程和注解注解缓存应用开发@Cacheable如果缓存中不存在目标值,则将调用目标方法并将返回的值存入缓存;如果存在,则直接返回缓存中的值,不会执行方法体。即使方法体内进行了数据库的......
  • ui自动化从登录到新增数据
    fromseleniumimportwebdriverfromtimeimportsleepfromselenium.webdriver.common.byimportBy#通过ID来定位driver=webdriver.Chrome()driver.maximize_window()driver.get('https://www.jdy.com/login/')#打开网站sleep(3)driver.find_element(By.ID,'......
  • Python Fire:自动生成命令行接口
    首先创建一个 student_file.pypipinstallfire使用 Fire 转换成命令行程序 1.默认方式importfiredefimport_file(fp):print("函数1打印结果:{}".format(fp))defexport_file(fp):print("函数2打印结果:{}".format(fp))if__name__=="__m......
  • 设计模式-行为型模式
    ⾏为模式:负责对象间的⾼效沟通和职责传递委派。PS:博客根据it老齐大话设计模式课程课件进行整理,IT老齐视频学习网站:https://www.itlaoqi.com包含的设计模式:策略模式、模板⽅法模式、观察者模式、迭代⼦模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模......
  • Shell 实现终端 rm 回收站效果
    本次实现的rm脚本的功能有:回收站收容删除的文件脚本记录删除的文件绝对路径和时间戳可根据脚本恢复删除的文件,并且可以只根据文件名匹配回收站所有的文件进行选择可直接删除文件可同时接收多个参数清空回收站后续会更新定时清空回收站的功能。TRASH_DIR="$HOME/.trash......