事件系统基本原理

事件系统可以将事件派发者与事件处理者解耦。例如,网络底层可以生成各种事件,在网络连接上后,网络底层只需将事件派发出去,而不需要关心到底哪些代码来响应连接上的逻辑。或者再比如,你注册、关注或者订阅某“大V”的社交消息后,“大V”发生的任何事件都会通知你,但他并不用了解粉丝们是如何为她喝彩或者疯狂的。

一个事件系统拥有如下特性:

  • 能够实现事件的一方,可以根据事件 ID 或名字注册对应的事件。
  • 事件发起者,会根据注册信息通知这些注册者。
  • 一个事件可以有多个实现方响应。
package main

import "fmt"

var eventList = make(map[string][]func(interface{}), 10) // 所有事件的列表

type EventClass struct {
}

func eventClass() *EventClass { // 实例化对象
	return &EventClass{}
}

func (e EventClass) registerEvent(name string, callback func(interface{})) {
	oneEventList := eventList[name]               // 获取总事件列表中某一个事件的列表
	oneEventList = append(oneEventList, callback) // 某一个事件的列表添加新事件
	eventList[name] = oneEventList                // 把某一个事件列表放回到总事件列表中
}

func (e EventClass) callEvent(name string, param interface{}) {
	oneEventList := eventList[name]      // 根据名字获取一个事件列表
	for _, event := range oneEventList { // 迭代事件列表,然后调用
		event(param)
	}
}

func networkRegister(i interface{}) {
	user, ok := i.(string) // 取出接口中的数据
	if ok {
		fmt.Println("user: ", user)
	}
}

func handleNetwork(i interface{}) {
	par := i.(map[string]interface{}) // 取出接口中的数据
	if id, ok := par["id"].([]int); ok {
		fmt.Println("handle id: ", id)
	}
	if user, ok := par["user"].([]string); ok {
		fmt.Println("handle user: ", user)
	}
}
func main() {
	eventObj := eventClass()                         // 调用实例化对象函数,并获取对象
	eventObj.registerEvent("net_1", networkRegister) // 注册一个事件
	eventObj.registerEvent("net_2", networkRegister) // 再次注册该事件
	eventObj.registerEvent("net_3", handleNetwork)   // 注册另一个处理事件
	eventObj.callEvent("net_1", "zhong")             // 调用事件
	eventObj.callEvent("net_2", "xiaohang")
	// 传递多种类型数据的参数
	pa := make(map[string]interface{})
	pa["id"] = []int{18, 22}
	pa["user"] = []string{"zhong", "hang"}
	eventObj.callEvent("net_3", pa)
}

// user:  zhong
// user:  xiaohang
// handle id:  [18 22]
// handle user:  [zhong hang]

一个完善的事件系统还会提供移除单个和所有事件的方法。