首页 > 其他分享 >Go 设计模式中观察者模式

Go 设计模式中观察者模式

时间:2023-11-10 11:34:47浏览次数:38  
标签:Observer 对象 主题 +-----------------+ 观察者 模式 Go 设计模式


鱼弦:内容合伙人、新星导师、全栈领域创作新星创作者 、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen)

                 

Go 设计模式中观察者模式_golang

 

观察者模式原理详细解释:
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,会通知所有观察者对象进行相应的更新。

观察者模式的核心思想是将观察者对象与主题对象解耦,使它们之间的依赖关系变得松散。主题对象负责管理观察者对象的注册、注销和通知操作,而观察者对象则负责定义更新的逻辑。

观察者模式通常包含以下几个角色:

  • 主题(Subject):定义了观察者对象的注册、注销和通知方法。
  • 具体主题(Concrete Subject):实现主题接口,维护观察者对象的列表,并在状态变化时通知观察者。
  • 观察者(Observer):定义了接收更新通知的方法。
  • 具体观察者(Concrete Observer):实现观察者接口,定义了具体的更新逻辑。

底层结构图:
以下是观察者模式的经典结构图:

+-----------------+        +-----------------+
|     Subject         |        |      Observer       |
+-----------------+        +-----------------+
| +Attach(observer) |        | +Update()            |
| +Detach(observer) |        +-----------------+
| +Notify()              |
+-----------------+
         ▲
         |
         |
+-----------------+
| ConcreteSubject |
+-----------------+
| -observers            |
| +SetState()            |
| +GetState()            |
+-----------------+
         ▲
         |
         |
+-----------------+
| ConcreteObserver |
+-----------------+
| +Update()            |
+-----------------+

在上述结构图中,Subject 是主题的角色,定义了观察者对象的注册、注销和通知方法。它通常包含一个观察者对象列表,并在状态变化时通知观察者。

Observer 是观察者的角色,定义了接收更新通知的方法。

ConcreteSubject 是具体主题的角色,实现了主题接口,并维护观察者对象的列表。在状态变化时,它通过调用观察者的 Update 方法来通知观察者。

ConcreteObserver 是具体观察者的角色,实现了观察者接口,并定义了具体的更新逻辑。当接收到主题的更新通知时,它执行相应的操作。

使用场景解释:
观察者模式适用于以下场景:

  1. 当一个对象的状态变化需要通知其他多个对象,并且这些对象的操作依赖于该状态变化时,可以考虑使用观察者模式。观察者模式提供了一种松耦合的方式,使主题对象和观察者对象之间的依赖关系减少。
  2. 当需要在系统中建立一种一对多的关系,一个主题对象可以同时通知多个观察者对象时,可以使用观察者模式。这样可以实现对象间的动态联动,使得系统更灵活、可扩展。
  3. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,但两者又需要独立变化时,可以使用观察者模式。观察者模式可以将两个方面的变化封装在各自的对象中,使其相互独立,提高系统的可维护性和可扩展性。

代码示例实现:
以下是一个使用Go语言实现观察者模式的简单示例:

package main

import "fmt"

// Subject 主题接口
type Subject interface {
	Attach(observer Observer) // 注册观察者
	Detach(observer Observer) // 注销观察者
	Notify()                  // 通知观察者
}

// Observer 观察者接口
type Observer interface {
	Update() // 更新操作
}

// ConcreteSubject 具体主题
type ConcreteSubject struct {
	observers []Observer
	state     string
}

func (s *ConcreteSubject) Attach(observer Observer) {
	s.observers = append(s.observers, observer)
}

func (s *ConcreteSubject) Detach(observer Observer) {
	for i, o := range s.observers {
		if o == observer {
			s.observers = append(s.observers[:i], s.observers[i+1:]...)
			break
		}
	}
}

func (s *ConcreteSubject) Notify() {
	for _, observer := range s.observers {
		observer.Update()
	}
}

func (s *ConcreteSubject) SetState(state string) {
	s.state = state
	s.Notify()
}

func (s *ConcreteSubject) GetState() string {
	return s.state
}

// ConcreteObserver 具体观察者
type ConcreteObserver struct {
	name string
}

func (o *ConcreteObserver) Update() {
	fmt.Printf("Observer %s received the update.\n", o.name)
}

func main() {
	subject := &ConcreteSubject{}

	observer1 := &ConcreteObserver{name: "Observer1"}
	observer2 := &ConcreteObserver{name: "Observer2"}

	subject.Attach(observer1)
	subject.Attach(observer2)

	subject.SetState("new state")

	subject.Detach(observer2)

	subject.SetState("another state")
}

在上述示例中,我们定义了 Subject 接口和 Observer 接口,分别表示主题和观察者。ConcreteSubject 结构体实现了 Subject 接口,负责维护观察者列表、注册观察者、注销观察者以及通知观察者的操作。ConcreteObserver 结构体实现了 Observer 接口,定义了更新操作的逻辑。

在 main 函数中,我们创建了一个具体主题对象 subject,并创建了两个具体观察者对象 observer1 和 observer2。通过调用 Attach 方法,我们将观察者对象注册到主题对象中。然后通过调用 SetState 方法改变主题对象的状态,从而触发通知操作。在观察者接收到更新通知时,会执行相应的操作。

文献材料链接:
以下是一些关于观察者模式的文献材料链接,供进一步学习和参考:

  1. Design Patterns: Elements of Reusable Object-Oriented Software (《设计模式:可复用面向对象软件的基础》) - 该书由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 编写,是关于设计模式的经典著作。其中包含了观察者模式的详细介绍和示例。
    链接:Amazon.com
  2. Head First Design Patterns (《Head First设计模式》) - 该书由 Eric Freeman、Elisabeth Robson、Bert Bates 和 Kathy Sierra 编写,以易于理解和有趣的方式介绍了设计模式。其中包含了观察者模式的详细解释和示例。
    链接:Amazon.com

当前都有哪些产品在使用观察者模式:

观察者模式在Java中的事件机制中得到了广泛应用。Java提供了一套事件和监听器的机制,用于处理对象之间的消息传递和事件触发。一些典型的Java产品和技术,如Swing GUI框架、JavaBeans、Java Message Service (JMS)等,都使用了观察者模式。

  • Swing GUI框架:Swing是Java中用于构建图形用户界面的框架,其中的事件机制就是基于观察者模式实现的。Swing中的组件(如按钮、文本框等)可以作为主题对象,而事件监听器则充当观察者,用于接收和处理组件的事件通知。
  • JavaBeans:JavaBeans是一种用于构建可重用组件的Java技术规范。在JavaBeans中,属性变化通知机制就是基于观察者模式实现的。JavaBeans中的属性可以作为主题对象,而属性变化监听器则充当观察者,用于接收和处理属性变化的通知。
  • Java Message Service (JMS):JMS是Java中用于实现分布式消息传递的API规范。JMS中的消息订阅和发布机制就是基于观察者模式实现的。JMS中的消息主题可以作为主题对象,而消息订阅者则充当观察者,用于接收和处理发布的消息。

除了上述产品和技术,观察者模式在许多其他领域也得到了广泛应用,例如Android开发中的事件监听、Spring框架中的事件驱动编程、消息队列系统等。观察者模式的灵活性和可扩展性使其成为软件开发中常用的设计模式之一。

标签:Observer,对象,主题,+-----------------+,观察者,模式,Go,设计模式
From: https://blog.51cto.com/chenfenglove/8294044

相关文章

  • Golang锁简单使用
    golang主要有两种锁:互斥锁和读写锁互斥锁Mutex用于提供一种加锁机制(LockingMechanism),保证同一时刻只有一个goroutine在临界区运行packagemainimport( "fmt" "sync" "time")funcmain(){ varmutexsync.Mutex x:=0 gofunc(){ mutex.Lock() x=x+1......
  • Golang服务端断线重连
    断线重连的逻辑很简单,就是把用户存到服务器内存中,当客户端再次登录的时候,判断内存中是否有用户的值,有的话替换packagemainimport( "fmt" "github.com/gorilla/websocket" "log" "net/http" "sync" "time")typeClientstruct{ conn*we......
  • 记录使用mongotemplete关于时间查询时的大坑
    1、问题:在使用条件查询mongdb数据库的时候,涉及到使用时间范围来查询数据,比如当时使用的是:1990-01-01T00:00:00到1900-02-02T00:00:00查询的是1月1号到1月2号两天的数据,但是在使用Query.query(criteria);进行查询的时候,和使用Aggregation.match(criteria);进行查询得出的结果不......
  • Go 面向接口编程
    接口有什么用?就是存储未实现的方法,作为实现的此方法的结构体的实例的句柄。typeSayerinterface{ say()}typeDogstruct{}typeCatstruct{}func(*Dog)say(){ fmt.Println("Woewwoew")}func(*Cat)say(){ fmt.Println("Meowmeow")}funcmain(){ va......
  • D - Good Tuple Problem atcoder abc 327
    D-GoodTupleProblemhttps://atcoder.jp/contests/abc327/tasks/abc327_d 思路https://www.zhihu.com/question/292465499判断二分图的常见方法是染色法:用两种颜色,对所有顶点逐个染色,且相邻顶点染不同的颜色如果发现相邻顶点染了同一种颜色,就认为此图不为二分图当所......
  • mongodb如何设置用户名和密码
    1.创建用户//连接到MongoDB数据库mongo//切换到admin数据库useadmin1.1创建root用户db.createUser({  user:"admin",  pwd:"admin123",  roles:[    {role:"userAdminAnyDatabase",db:"admin"},    {role:"dbAdminAnyDatab......
  • 解锁设计模式的神秘面纱:编写无懈可击的代码之单例设计模式
    前言单例设计模式是23种设计模式中最常用的设计模式之一,无论是三方类库还是日常开发几乎都有单例设计模式的影子。单例设计模式提供了一种在多线程情况下保证实例唯一性的解决方案。单例设计模式虽然简单,但是实现方案却非常多,大体上有以下7种最常见的方式。饿汉模式所谓饿汉式,就是......
  • 【django框架】共4大模块50页md学习文档 第5篇:django的请求与响应详解
    当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源PythonWeb框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用整套Django笔记直接地址:请移步这里共10章,31子模块请求与响应学习目标掌握r......
  • 【Django-DRF笔记】使用md笔记0基础到高手. 第(5)篇:Django-DRF序列化和反序列化
    本文从分析现在流行的前后端分离Web应用模式说起,然后介绍如何设计RESTAPI,通过使用Django来实现一个RESTAPI为例,明确后端开发RESTAPI要做的最核心工作,然后介绍DjangoRESTframework能帮助我们简化开发RESTAPI的工作。DRF完整版笔记直接地址:请移步这里共5章,24子模块,总计......
  • Django 三板斧的使用 链接数据库
    Django三板斧的使用全局配置文件静态文件的配置request对象的几个方法pycharm链接数据库MySQLDjango链接数据库MySQLORM的使用今日内容详细三板斧的使用三个方法:HttpResponserenderredirectdefindex(request):print('request')#returnHttpResponse......