首页 > 其他分享 >go-interface

go-interface

时间:2024-09-27 13:45:44浏览次数:9  
标签:EventHandler string interface func go gin type event

实现一个事件通知的处理, 收到这个消息后, 灵活的定义要执行的方法,使用接口实现

1. 第一种实现

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// 定义事件处理接口
type EventHandler interface {
	HandleEvent(data string) error
}

// EmailNotifier 实现了 EventHandler 接口
type EmailNotifier struct{}

func (e *EmailNotifier) HandleEvent(data string) error {
	// 发送邮件逻辑
	// 这里可以根据需求实现邮件发送
	return nil
}

// SMSNotifier 实现了 EventHandler 接口
type SMSNotifier struct{}

func (s *SMSNotifier) HandleEvent(data string) error {
	// 发送短信逻辑
	// 这里可以根据需求实现短信发送
	return nil
}

func main() {
	router := gin.Default()

	// 创建处理器实例
	emailHandler := &EmailNotifier{}
	smsHandler := &SMSNotifier{}

	// 定义事件通知的路由
	router.POST("/notify", func(c *gin.Context) {
		var requestData struct {
			EventType string `json:"event_type"`
			Data      string `json:"data"`
		}

		if err := c.ShouldBindJSON(&requestData); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		var handler EventHandler

		// 根据事件类型选择处理器
		switch requestData.EventType {
		case "email":
			handler = emailHandler
		case "sms":
			handler = smsHandler
		default:
			c.JSON(http.StatusBadRequest, gin.H{"error": "unknown event type"})
			return
		}

		// 处理事件
		if err := handler.HandleEvent(requestData.Data); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}

		c.JSON(http.StatusOK, gin.H{"status": "event processed"})
	})

	router.Run(":8080") // 启动服务器
}

2. 第二种实现

引入观察者模式,使得事件通知更加灵活和可扩展。通过使用一个事件总线,将事件发布和处理解耦,可以轻松添加新的事件处理器,而不需要修改现有的代码。

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"sync"
)

// Event 事件结构
type Event struct {
	Type string
	Data string
}

// EventHandler 事件处理器接口
type EventHandler interface {
	HandleEvent(event Event) error
}

// EventBus 事件总线
type EventBus struct {
	mu       sync.RWMutex
	handlers map[string][]EventHandler
}

// NewEventBus 创建新的事件总线
func NewEventBus() *EventBus {
	return &EventBus{
		handlers: make(map[string][]EventHandler),
	}
}

// Register 注册事件处理器, `eventType` 事件类型, `handler` 事件处理器 handler 实现了 `EventHandler` 接口
func (eb *EventBus) Register(eventType string, handler EventHandler) {
	eb.mu.Lock()
	defer eb.mu.Unlock()
	eb.handlers[eventType] = append(eb.handlers[eventType], handler)
}

// Publish 发布事件
func (eb *EventBus) Publish(event Event) {
	eb.mu.RLock()
	defer eb.mu.RUnlock()
	if handlers, ok := eb.handlers[event.Type]; ok {
		for _, handler := range handlers {
			go handler.HandleEvent(event)
		}
	}
}

// EmailNotifier
type EmailNotifier struct{}

func (e *EmailNotifier) HandleEvent(event Event) error {
	// 发送邮件逻辑
	// 实际的邮件发送实现
	println("send email to:", event.Data)
	return nil
}

// SMSNotifier
type SMSNotifier struct{}

func (s *SMSNotifier) HandleEvent(event Event) error {
	// 发送短信逻辑
	// 实际的短信发送实现
	println("send sms to:", event.Data)
	return nil
}

func main() {
	router := gin.Default()
	eventBus := NewEventBus()

	// 注册处理器
	eventBus.Register("email", &EmailNotifier{})
	eventBus.Register("sms", &SMSNotifier{})

	// 定义事件通知的路由
	router.POST("/notify", func(c *gin.Context) {
		var requestData struct {
			EventType string `json:"event_type"`
			Data      string `json:"data"`
		}

		if err := c.ShouldBindJSON(&requestData); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		event := Event{
			Type: requestData.EventType,
			Data: requestData.Data,
		}

		// 发布事件
		eventBus.Publish(event)

		c.JSON(http.StatusOK, gin.H{"status": "event published"})
	})

	router.Run(":8080") // 启动服务器
}

请求

http://localhost:8080/notify


{
    "event_type": "email",
    "data": "This is an email notification."
}

 

标签:EventHandler,string,interface,func,go,gin,type,event
From: https://www.cnblogs.com/wanghhhh/p/18435540

相关文章

  • 基于Django的教师公寓人脸识别系统的开发与实现
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • Typora图床配置(用自带的 PicGo-Core(command line) 插件GitHub
    1.准备工作在GitHub申请token,申请的token只出现一次!下载node.js并安装,node.js官网,如果是win7系统,可以下载2020的最新版,笔者是win7,64位的系统,下载的是node-v15.5.0-x64.msi.2.在Typora中下载PicGo-Core(commandline)插件打开Typora,依次点击文件-偏好设置-图像;按......
  • [含文档+PPT+源码等]精品大数据项目-Django基于Hadoop实现的气象分析系统
    大数据项目——Django基于Hadoop实现的气象分析系统的背景,可以从以下几个方面进行阐述:一、技术背景Hadoop的广泛应用:Hadoop是一个由Apache基金会所开发的分布式系统基础架构,它利用集群的威力进行高速运算和存储。Hadoop以其高可靠性、高扩展性、高效性、高容错性等特点,在......
  • Go 语言微服务中的高并发实现
    目录Go语言微服务中的高并发实现一、微服务与高并发的需求二、Go语言的并发优势三、示例:高并发的用户服务微服务(一)定义服务结构体和方法(二)模拟高并发请求四、总结在微服务架构中,高并发处理能力是至关重要的。Go语言以其原生支持并发的特性,在构建高并发微服务方面......
  • go logrus输出json日志并转储
    相比于klog,logrus支持输出json日志,但是默认time不在最前面,而在最后,因为日志输出时按照key字母顺序排序。gogetgithub.com/sirupsen/logrusgogetgithub.com/natefinch/lumberjackpackagemainimport( "fmt" "io" "os" "path/filepath" "runtime"......
  • 正在寻找 4 中的开源 Google Analytics 替代品?
    如果您是开发人员,您可能已经花了一些时间寻找合适的分析工具。我们在你之前做到了!大多数人默认使用GoogleAnalytics,但它并不总是完美的选择,特别是如果您担心设置复杂性、隐私、持续支持(作为小团队)或定制。今天我们向您介绍Litlyx,它是GoogleAnalytics的开源替代品,旨在简化您......
  • go json配置
    问题1:被序列化的结构体首字母必须大写typeStudentstruct{ sexstring ageint}如果被序列化的结构体首字母不大写,那么序列化结果是空。告警内容structtype'test/json_config.Student'doesn'thaveanyexportedfields,norcustommarshaling问题2:不指定json配置后......
  • go panic interface conversion interface {} is float64, not int
    packagemainimport( "encoding/json" "log")typeStudentstruct{ Sexstring`json:"sex"` Ageint`json:"age"`}funcmain(){ s1:=&Student{ Sex:"s1", Age:20, } str1,err:=json.Ma......
  • 【Golang】双节点集群etcd未组成集群vip切换时序
    目录1、背景2、时序图1、背景在vip(虚拟ip)可以从一个节点切换到另一个节点,但etcd未组成集群的环境中,与etcd的连接会断开重连,但同一个key在不同节点的版本可能会不一样导致etcd服务器不向客户端推送数据,也就是客户端watch失效了,具体解决方法参考之前的重连方法。下面......
  • 将 MongoDB 与 Cloudflare Workers 结合使用
    当我尝试使用CloudflareWorkers和MongoDB创建一个简单的项目时,我遇到了多个错误,导致集成过程变得困难。在我的研究过程中,我发现了一些讨论MongoDB和CloudflareWorkers之间的兼容性问题的文章。MongoDB和CloudflareWorkers兼容性问题我发现了一篇题为“MongoDB无法......