go-interface实现一个事件通知的处理

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

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."
}

 

posted @ 2024-09-27 13:50  wanghhhh  阅读(61)  评论(0)    收藏  举报