返回

Go代码减脂,巧用观察者模式显瘦几圈!

后端

今天学习一下用 Go 实现观察者模式,观察者模式主要是用来实现事件驱动编程。事件驱动编程的应用还是挺广的,除了我们都知道的能够用来解耦:用户修改密码后,给用户发短信进行风险提示之类的典型场景,在微服务开发中也经常被用到,比如服务状态变更通知,分布式任务调度等等。

观察者模式是一种软件设计模式,允许一个对象(发布者)将它自身的状态改变通知给一系列其他对象(订阅者)。这样,当发布者发生改变时,所有订阅者都会自动收到通知,并根据需要做出相应反应。

观察者模式有很多好处,比如:

  • 解耦: 发布者和订阅者之间是松散耦合的,这意味着它们可以独立于对方改变。这使得代码更容易维护和扩展。
  • 可伸缩性: 观察者模式很容易扩展,只需要添加新的订阅者即可。这使得它非常适合于需要处理大量事件的系统。
  • 异步处理: 订阅者可以异步处理事件,这可以提高系统的性能。

Go中实现观察者模式

在 Go 中实现观察者模式非常简单,只需要几个步骤:

  1. 定义一个接口,代表订阅者。
  2. 定义一个结构体,代表发布者。
  3. 在发布者结构体中,添加一个订阅者列表。
  4. 在发布者结构体中,添加一个方法,用于添加和删除订阅者。
  5. 在发布者结构体中,添加一个方法,用于通知所有订阅者。
  6. 定义一个结构体,代表事件。
  7. 在事件结构体中,添加一个字段,代表事件类型。
  8. 在事件结构体中,添加一个字段,代表事件数据。

下面是一个简单的例子,演示如何使用观察者模式在 Go 中实现事件驱动编程:

package main

import (
	"fmt"
)

// 定义一个接口,代表订阅者。
type Subscriber interface {
	// 处理事件。
	HandleEvent(event Event)
}

// 定义一个结构体,代表发布者。
type Publisher struct {
	// 订阅者列表。
	subscribers []Subscriber
}

// 在发布者结构体中,添加一个方法,用于添加订阅者。
func (p *Publisher) AddSubscriber(subscriber Subscriber) {
	p.subscribers = append(p.subscribers, subscriber)
}

// 在发布者结构体中,添加一个方法,用于删除订阅者。
func (p *Publisher) RemoveSubscriber(subscriber Subscriber) {
	for i, s := range p.subscribers {
		if s == subscriber {
			p.subscribers = append(p.subscribers[:i], p.subscribers[i+1:]...)
			break
		}
	}
}

// 在发布者结构体中,添加一个方法,用于通知所有订阅者。
func (p *Publisher) NotifySubscribers(event Event) {
	for _, s := range p.subscribers {
		s.HandleEvent(event)
	}
}

// 定义一个结构体,代表事件。
type Event struct {
	// 事件类型。
	Type string

	// 事件数据。
	Data interface{}
}

// 在事件结构体中,添加一个字段,代表事件类型。
// 在事件结构体中,添加一个字段,代表事件数据。

// 定义一个订阅者结构体。
type MySubscriber struct {
	name string
}

// 实现Subscriber接口的HandleEvent方法。
func (s *MySubscriber) HandleEvent(event Event) {
	fmt.Printf("MySubscriber %s received event %s with data %v\n", s.name, event.Type, event.Data)
}

func main() {
	// 创建一个发布者。
	publisher := &Publisher{}

	// 创建两个订阅者。
	subscriber1 := &MySubscriber{name: "Subscriber 1"}
	subscriber2 := &MySubscriber{name: "Subscriber 2"}

	// 将订阅者添加到发布者。
	publisher.AddSubscriber(subscriber1)
	publisher.AddSubscriber(subscriber2)

	// 创建一个事件。
	event := Event{Type: "test", Data: "Hello, world!"}

	// 发布事件。
	publisher.NotifySubscribers(event)
}

运行上面的代码,输出结果如下:

MySubscriber Subscriber 1 received event test with data Hello, world!
MySubscriber Subscriber 2 received event test with data Hello, world!

这个例子演示了如何使用观察者模式在 Go 中实现事件驱动编程。观察者模式是一种非常有用的设计模式,可以帮助我们编写出更灵活、更易维护的代码。