golang观察者设计模式

news/2025/1/12 13:22:21/

观察者模式简介

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者对象都会得到通知并自动更新。观察者模式使得对象之间的耦合度降低,提高了系统的灵活性和可维护性。

结构

观察者模式包含以下几个角色:
1. 主题(Subject):定义了观察者注册、移除和通知的方法。
2. 具体主题(ConcreteSubject):实现主题接口,维护一个观察者列表,当状态发生变化时通知所有观察者。
3. 观察者(Observer):定义了一个更新接口,当接收到主题的通知时更新自己。
4. 具体观察者(ConcreteObserver):实现观察者接口,更新自己的状态以与主题的状态保持一致。

应用场景

  • 当一个对象的状态或数据更新需要其他对象同步更新,或者一个对象的更新需要依赖另一个对象的更新时,可以使用观察者模式。
  • 适用于对象只需要通知其他对象其状态变化而不需要知道其他对象细节的情况,比如消息推送机制。

优缺点

优点

  • 降低耦合度:观察者模式通过将观察者和主题解耦,使得它们可以独立变化,提高了系统的灵活性和可维护性。
  • 支持广播通信:主题对象可以向所有注册的观察者发送通知,实现广播通信。

缺点

  • 可能导致性能问题:如果观察者数量过多,通知所有观察者可能会导致性能问题。
  • 可能导致内存泄漏:如果观察者没有及时解除注册,可能会导致内存泄漏。

示例

在Go语言中实现观察者模式可以通过接口和通道(channel)来实现。下面是一个简单的例子,演示如何使用Go语言实现观察者模式:

package mainimport "fmt"// Observer接口定义了观察者应该实现的方法。
type Observer interface {RevMsg(wd int) // 接受信息
}// Subject接口定义了主题(被观察者)应该实现的方法。
type Subject interface {SendMsg(wd int)     // 发送消息给所有注册的观察者Notify()           // 通知所有注册的观察者RegisterObserver(Observer) // 注册一个新的观察者
}// User结构体表示一个具体的观察者。
type User struct {Name string
}// RevMsg是User结构体的方法,实现了Observer接口。
// 它是一个指针接收者方法,这意味着它会操作原始的User实例。
func (u *User) RevMsg(wd int) {fmt.Println(u.Name, "现在温度", wd, "℃")
}// WeatherZhan结构体表示主题(被观察者),维护着一组观察者。
type WeatherZhan struct {ObserverList []Observer // 观察者列表wd           int        // 温度数据
}// SendMsg更新WeatherZhan中的温度数据,并调用Notify通知所有观察者。
func (w *WeatherZhan) SendMsg(wd int) {w.wd = wdw.Notify()
}// Notify遍历所有的观察者,并调用它们的RevMsg方法来通知他们最新的温度数据。
func (w *WeatherZhan) Notify() {for _, observer := range w.ObserverList {observer.RevMsg(w.wd)}
}// RegisterObserver将新的观察者添加到WeatherZhan的观察者列表中。
func (w *WeatherZhan) RegisterObserver(observer Observer) {w.ObserverList = append(w.ObserverList, observer)
}func main() {// 创建一个新的WeatherZhan实例。zhan := WeatherZhan{}// 创建两个User实例,代表两个不同的观察者。u1 := User{Name: "张三",}u2 := User{Name: "李四",}// 将两个观察者注册到WeatherZhan。// 注意这里我们传递的是User实例的指针,因为User的RevMsg方法是指针接收者。zhan.RegisterObserver(&u1)zhan.RegisterObserver(&u2)// 更新WeatherZhan的温度数据,并通过SendMsg通知所有已注册的观察者。zhan.SendMsg(8)
}


http://www.ppmy.cn/news/1562514.html

相关文章

73.矩阵置零 python

矩阵置零 题目题目描述示例 1:示例 2:提示: 题解思路分析Python 实现代码代码解释提交结果 题目 题目描述 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例…

网络编程的进程查看连接描述符信息等

一.查看当前进程的socket对应的fd信息 1. lsof lsof&#xff08;List Open Files&#xff09;命令可以列出系统中所有打开的文件的信息&#xff0c;包括 socket。 用法 要查看特定进程的 socket 信息&#xff0c;可以使用以下命令&#xff1a; lsof -p <pid> | grep…

如何构建多层决策树

构建一颗多层的决策树时&#xff0c;通过递归选择最佳划分特征&#xff08;依据 信息增益 或 基尼系数&#xff09;对数据集进行划分&#xff0c;直到满足停止条件&#xff08;例如叶节点纯度达到要求或树的深度限制&#xff09;。以下是基于 信息增益 和 基尼系数 的递推公式和…

12工具篇(D2_Commons-lang3)

目录 一、基本介绍 二、commons-lang3库的引用 三、常用工具类 1. StringUtils 2. RandomStringUtils 3. NumberUtils 4. ArrayUtils 5. DateUtils 6. StringUtile 7. BeanUtils 7.1 基本介绍 7.2 JavaBean 7.3 两个概念 7.4 常用操作 7.5 应用 1. JavaBean 的属…

ISP架构方案

外置 ISP 架构 外置 ISP 架构是指在 AP 外部单独布置 ISP 芯片用于图像信号处理。外置 ISP 的架构图一般如下所示&#xff1a; 外置 ISP 架构的优点主要有&#xff1a; 能够提供更优秀的图像质量&#xff1a;在激烈的市场竞争下&#xff0c;能够存活到现在的外置 ISP 生产厂商在…

飞书二维码登录注意点

1.前端SDK版本 第一个手机端授权后、网页端还需要点击一次授权 授权后会跳转到redirect_uri页面&#xff0c;连接会携带code<script src"https://lf-package-cn.feishucdn.com/obj/feishu-static/lark/passport/qrcode/LarkSSOSDKWebQRCode-1.0.3.js"></scr…

k8s之pod生命周期

一.pod生命周期:pod对象从创建开始到终止的过程1.作用:复杂服务的启动顺序,依赖关系,容器服务启动前的相关操作,配置文件生成,依赖服务检测等...2.生命周期流程:初始化容器--主容器--启动后回调函数-->启动,生命,就绪探针-->关闭前回调函数初始化容器执行&#xff1a;执行…

istio-proxy内存指标

在 Istio 环境中&#xff0c;istio-proxy 是 Envoy 的边车代理容器。通过运行命令 curl localhost:15000/memory&#xff0c;或者curl localhost:15000/stats 可以查询 Envoy 的内存统计信息。以下是典型返回结果的结构和意义&#xff1a; 返回结果单位是bytes&#xff0c;需/…